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"
4462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/objects-inl.h"
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 {
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal {
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool CpuFeatures::SupportsCrankshaft() { return true; }
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
51f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochbool CpuFeatures::SupportsSimd128() { return false; }
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const byte kCallOpcode = 0xE8;
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const int kNoCodeAgeSequenceLength = 5;
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// The modes possibly affected by apply must be in kApplyMask.
58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid RelocInfo::apply(intptr_t delta) {
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (IsRuntimeEntry(rmode_) || IsCodeTarget(rmode_)) {
60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int32_t* p = reinterpret_cast<int32_t*>(pc_);
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    *p -= delta;  // Relocate entry.
62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (IsCodeAgeSequence(rmode_)) {
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (*pc_ == kCallOpcode) {
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1);
65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      *p -= delta;  // Relocate entry.
66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (IsDebugBreakSlot(rmode_) && IsPatchedDebugBreakSlotSequence()) {
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Special handling of a debug break slot when a break point is set (call
69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // instruction has been inserted).
70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int32_t* p = reinterpret_cast<int32_t*>(
71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        pc_ + Assembler::kPatchDebugBreakSlotAddressOffset);
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    *p -= delta;  // Relocate entry.
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (IsInternalReference(rmode_)) {
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // absolute code pointer inside code object moves with the code object.
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int32_t* p = reinterpret_cast<int32_t*>(pc_);
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    *p += delta;  // Relocate entry.
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAddress RelocInfo::target_address() {
82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_));
83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Assembler::target_address_at(pc_, host_);
84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAddress RelocInfo::target_address_address() {
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              || rmode_ == EMBEDDED_OBJECT
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              || rmode_ == EXTERNAL_REFERENCE);
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return reinterpret_cast<Address>(pc_);
91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAddress RelocInfo::constant_pool_entry_address() {
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NULL;
97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint RelocInfo::target_address_size() {
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Assembler::kSpecialTargetSize;
102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochObject* RelocInfo::target_object() {
106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Memory::Object_at(pc_);
108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Object> RelocInfo::target_object_handle(Assembler* origin) {
112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Memory::Object_Handle_at(pc_);
114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RelocInfo::set_target_object(Object* target,
118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  WriteBarrierMode write_barrier_mode,
119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  ICacheFlushMode icache_flush_mode) {
120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Memory::Object_at(pc_) = target;
122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Assembler::FlushICache(isolate_, pc_, sizeof(Address));
124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (write_barrier_mode == UPDATE_WRITE_BARRIER &&
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      host() != NULL &&
127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      target->IsHeapObject()) {
128f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    host()->GetHeap()->RecordWriteIntoCode(host(), this, target);
1293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(
1303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        host(), this, HeapObject::cast(target));
131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAddress RelocInfo::target_external_reference() {
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rmode_ == RelocInfo::EXTERNAL_REFERENCE);
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Memory::Address_at(pc_);
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAddress RelocInfo::target_internal_reference() {
142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(rmode_ == INTERNAL_REFERENCE);
143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return Memory::Address_at(pc_);
144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAddress RelocInfo::target_internal_reference_address() {
148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(rmode_ == INTERNAL_REFERENCE);
149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return reinterpret_cast<Address>(pc_);
150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAddress RelocInfo::target_runtime_entry(Assembler* origin) {
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsRuntimeEntry(rmode_));
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return reinterpret_cast<Address>(*reinterpret_cast<int32_t*>(pc_));
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RelocInfo::set_target_runtime_entry(Address target,
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                         WriteBarrierMode write_barrier_mode,
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                         ICacheFlushMode icache_flush_mode) {
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsRuntimeEntry(rmode_));
163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (target_address() != target) {
164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_target_address(target, write_barrier_mode, icache_flush_mode);
165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Cell> RelocInfo::target_cell_handle() {
170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rmode_ == RelocInfo::CELL);
171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address address = Memory::Address_at(pc_);
172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Handle<Cell>(reinterpret_cast<Cell**>(address));
173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochCell* RelocInfo::target_cell() {
177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rmode_ == RelocInfo::CELL);
178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Cell::FromValueAddress(Memory::Address_at(pc_));
179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RelocInfo::set_target_cell(Cell* cell,
183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                WriteBarrierMode write_barrier_mode,
184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                ICacheFlushMode icache_flush_mode) {
185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(cell->IsCell());
186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rmode_ == RelocInfo::CELL);
187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address address = cell->address() + Cell::kValueOffset;
188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Memory::Address_at(pc_) = address;
189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Assembler::FlushICache(isolate_, pc_, sizeof(Address));
191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL) {
193109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(host(), this,
194109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                                                  cell);
195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Object> RelocInfo::code_age_stub_handle(Assembler* origin) {
200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE);
201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(*pc_ == kCallOpcode);
202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Memory::Object_Handle_at(pc_ + 1);
203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochCode* RelocInfo::code_age_stub() {
207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE);
208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(*pc_ == kCallOpcode);
209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Code::GetCodeFromTargetAddress(
210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Assembler::target_address_at(pc_ + 1, host_));
211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RelocInfo::set_code_age_stub(Code* stub,
215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  ICacheFlushMode icache_flush_mode) {
216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(*pc_ == kCallOpcode);
217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE);
218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Assembler::set_target_address_at(
219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      isolate_, pc_ + 1, host_, stub->instruction_start(), icache_flush_mode);
220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAddress RelocInfo::debug_call_address() {
224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence());
225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Address location = pc_ + Assembler::kPatchDebugBreakSlotAddressOffset;
226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return Assembler::target_address_at(location, host_);
227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid RelocInfo::set_debug_call_address(Address target) {
231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence());
232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Address location = pc_ + Assembler::kPatchDebugBreakSlotAddressOffset;
233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Assembler::set_target_address_at(isolate_, location, host_, target);
234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (host() != NULL) {
235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Object* target_code = Code::GetCodeFromTargetAddress(target);
236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(
237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        host(), this, HeapObject::cast(target_code));
238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RelocInfo::WipeOut() {
243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (IsEmbeddedObject(rmode_) || IsExternalReference(rmode_) ||
244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      IsInternalReference(rmode_)) {
245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Memory::Address_at(pc_) = NULL;
246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)) {
247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Effectively write zero into the relocation.
248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Assembler::set_target_address_at(isolate_, pc_, host_,
249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                     pc_ + sizeof(int32_t));
250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    UNREACHABLE();
252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
255bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochtemplate <typename ObjectVisitor>
256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) {
257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RelocInfo::Mode mode = rmode();
258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (mode == RelocInfo::EMBEDDED_OBJECT) {
259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    visitor->VisitEmbeddedPointer(this);
260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Assembler::FlushICache(isolate, pc_, sizeof(Address));
261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (RelocInfo::IsCodeTarget(mode)) {
262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    visitor->VisitCodeTarget(this);
263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (mode == RelocInfo::CELL) {
264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    visitor->VisitCell(this);
265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    visitor->VisitExternalReference(this);
267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (mode == RelocInfo::INTERNAL_REFERENCE) {
268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    visitor->VisitInternalReference(this);
269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (RelocInfo::IsCodeAgeSequence(mode)) {
270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    visitor->VisitCodeAgeSequence(this);
271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (RelocInfo::IsDebugBreakSlot(mode) &&
272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             IsPatchedDebugBreakSlotSequence()) {
273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    visitor->VisitDebugTarget(this);
274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (IsRuntimeEntry(mode)) {
275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    visitor->VisitRuntimeEntry(this);
276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<typename StaticVisitor>
281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RelocInfo::Visit(Heap* heap) {
282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RelocInfo::Mode mode = rmode();
283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (mode == RelocInfo::EMBEDDED_OBJECT) {
284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StaticVisitor::VisitEmbeddedPointer(heap, this);
285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Assembler::FlushICache(heap->isolate(), pc_, sizeof(Address));
286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (RelocInfo::IsCodeTarget(mode)) {
287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StaticVisitor::VisitCodeTarget(heap, this);
288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (mode == RelocInfo::CELL) {
289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StaticVisitor::VisitCell(heap, this);
290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StaticVisitor::VisitExternalReference(this);
292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (mode == RelocInfo::INTERNAL_REFERENCE) {
293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    StaticVisitor::VisitInternalReference(this);
294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (RelocInfo::IsCodeAgeSequence(mode)) {
295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StaticVisitor::VisitCodeAgeSequence(heap, this);
296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (RelocInfo::IsDebugBreakSlot(mode) &&
297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             IsPatchedDebugBreakSlotSequence()) {
298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StaticVisitor::VisitDebugTarget(heap, this);
299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (IsRuntimeEntry(mode)) {
300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StaticVisitor::VisitRuntimeEntry(this);
301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochImmediate::Immediate(int x)  {
307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  x_ = x;
308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  rmode_ = RelocInfo::NONE32;
309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochImmediate::Immediate(Address x, RelocInfo::Mode rmode) {
3123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  x_ = reinterpret_cast<int32_t>(x);
3133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  rmode_ = rmode;
3143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochImmediate::Immediate(const ExternalReference& ext) {
317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  x_ = reinterpret_cast<int32_t>(ext.address());
318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  rmode_ = RelocInfo::EXTERNAL_REFERENCE;
319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochImmediate::Immediate(Label* internal_offset) {
323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  x_ = reinterpret_cast<int32_t>(internal_offset);
324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  rmode_ = RelocInfo::INTERNAL_REFERENCE;
325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochImmediate::Immediate(Handle<Object> handle) {
329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AllowDeferredHandleDereference using_raw_address;
330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Verify all Objects referred by code are NOT in new space.
331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* obj = *handle;
332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (obj->IsHeapObject()) {
333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    x_ = reinterpret_cast<intptr_t>(handle.location());
334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    rmode_ = RelocInfo::EMBEDDED_OBJECT;
335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // no relocation needed
337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    x_ =  reinterpret_cast<intptr_t>(obj);
338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    rmode_ = RelocInfo::NONE32;
339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochImmediate::Immediate(Smi* value) {
344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  x_ = reinterpret_cast<intptr_t>(value);
345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  rmode_ = RelocInfo::NONE32;
346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochImmediate::Immediate(Address addr) {
350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  x_ = reinterpret_cast<int32_t>(addr);
351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  rmode_ = RelocInfo::NONE32;
352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::emit(uint32_t x) {
356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *reinterpret_cast<uint32_t*>(pc_) = x;
357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  pc_ += sizeof(uint32_t);
358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::emit_q(uint64_t x) {
362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  *reinterpret_cast<uint64_t*>(pc_) = x;
363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  pc_ += sizeof(uint64_t);
364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::emit(Handle<Object> handle) {
368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AllowDeferredHandleDereference heap_object_check;
369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Verify all Objects referred by code are NOT in new space.
370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* obj = *handle;
371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (obj->IsHeapObject()) {
372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    emit(reinterpret_cast<intptr_t>(handle.location()),
373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         RelocInfo::EMBEDDED_OBJECT);
374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // no relocation needed
376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    emit(reinterpret_cast<intptr_t>(obj));
377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::emit(uint32_t x, RelocInfo::Mode rmode, TypeFeedbackId id) {
382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (rmode == RelocInfo::CODE_TARGET && !id.IsNone()) {
383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    RecordRelocInfo(RelocInfo::CODE_TARGET_WITH_ID, id.ToInt());
384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (!RelocInfo::IsNone(rmode)
385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      && rmode != RelocInfo::CODE_AGE_SEQUENCE) {
386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    RecordRelocInfo(rmode);
387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(x);
389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::emit(Handle<Code> code,
393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                     RelocInfo::Mode rmode,
394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                     TypeFeedbackId id) {
395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AllowDeferredHandleDereference embedding_raw_address;
396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(reinterpret_cast<intptr_t>(code.location()), rmode, id);
397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::emit(const Immediate& x) {
401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (x.rmode_ == RelocInfo::INTERNAL_REFERENCE) {
402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Label* label = reinterpret_cast<Label*>(x.x_);
403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    emit_code_relative_offset(label);
404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return;
405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!RelocInfo::IsNone(x.rmode_)) RecordRelocInfo(x.rmode_);
407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(x.x_);
408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::emit_code_relative_offset(Label* label) {
412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (label->is_bound()) {
413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int32_t pos;
414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    pos = label->pos() + Code::kHeaderSize - kHeapObjectTag;
415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    emit(pos);
416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    emit_disp(label, Displacement::CODE_RELATIVE);
418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid Assembler::emit_b(Immediate x) {
4223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  DCHECK(x.is_int8() || x.is_uint8());
4233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  uint8_t value = static_cast<uint8_t>(x.x_);
4243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  *pc_++ = value;
4253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::emit_w(const Immediate& x) {
428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(RelocInfo::IsNone(x.rmode_));
429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint16_t value = static_cast<uint16_t>(x.x_);
430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  reinterpret_cast<uint16_t*>(pc_)[0] = value;
431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  pc_ += sizeof(uint16_t);
432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAddress Assembler::target_address_at(Address pc, Address constant_pool) {
436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return pc + sizeof(int32_t) + *reinterpret_cast<int32_t*>(pc);
437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::set_target_address_at(Isolate* isolate, Address pc,
441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                      Address constant_pool, Address target,
442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      ICacheFlushMode icache_flush_mode) {
443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int32_t* p = reinterpret_cast<int32_t*>(pc);
444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *p = target - (pc + sizeof(int32_t));
445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Assembler::FlushICache(isolate, p, sizeof(int32_t));
447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
45062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochAddress Assembler::target_address_at(Address pc, Code* code) {
45162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Address constant_pool = code ? code->constant_pool() : NULL;
45262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return target_address_at(pc, constant_pool);
45362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
45462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
45562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid Assembler::set_target_address_at(Isolate* isolate, Address pc, Code* code,
45662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                      Address target,
45762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                      ICacheFlushMode icache_flush_mode) {
45862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Address constant_pool = code ? code->constant_pool() : NULL;
45962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  set_target_address_at(isolate, pc, constant_pool, target, icache_flush_mode);
46062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAddress Assembler::target_address_from_return_address(Address pc) {
463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return pc - kCallTargetAddressOffset;
464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDisplacement Assembler::disp_at(Label* L) {
468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Displacement(long_at(L->pos()));
469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::disp_at_put(Label* L, Displacement disp) {
473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  long_at_put(L->pos(), disp.data());
474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::emit_disp(Label* L, Displacement::Type type) {
478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Displacement disp(L, type);
479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  L->link_to(pc_offset());
480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  emit(static_cast<int>(disp.data()));
481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::emit_near_disp(Label* L) {
485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  byte disp = 0x00;
486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (L->is_near_linked()) {
487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int offset = L->near_link_pos() - pc_offset();
488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(is_int8(offset));
489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    disp = static_cast<byte>(offset & 0xFF);
490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  L->link_to(pc_offset(), Label::kNear);
492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *pc_++ = disp;
493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::deserialization_set_target_internal_reference_at(
497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Isolate* isolate, Address pc, Address target, RelocInfo::Mode mode) {
498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Memory::Address_at(pc) = target;
499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Operand::set_modrm(int mod, Register rm) {
503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((mod & -4) == 0);
504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buf_[0] = mod << 6 | rm.code();
505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  len_ = 1;
506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Operand::set_sib(ScaleFactor scale, Register index, Register base) {
510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(len_ == 1);
511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((scale & -4) == 0);
512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Use SIB with no index register only for base esp.
513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!index.is(esp) || base.is(esp));
514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buf_[1] = scale << 6 | index.code() << 3 | base.code();
515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  len_ = 2;
516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Operand::set_disp8(int8_t disp) {
520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(len_ == 1 || len_ == 2);
521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *reinterpret_cast<int8_t*>(&buf_[len_++]) = disp;
522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Operand::set_dispr(int32_t disp, RelocInfo::Mode rmode) {
526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(len_ == 1 || len_ == 2);
527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int32_t* p = reinterpret_cast<int32_t*>(&buf_[len_]);
528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *p = disp;
529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  len_ += sizeof(int32_t);
530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  rmode_ = rmode;
531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochOperand::Operand(Register reg) {
534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // reg
535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_modrm(3, reg);
536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochOperand::Operand(int32_t disp, RelocInfo::Mode rmode) {
540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // [disp/r]
541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_modrm(0, ebp);
542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_dispr(disp, rmode);
543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochOperand::Operand(Immediate imm) {
547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // [disp/r]
548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_modrm(0, ebp);
549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_dispr(imm.x_, imm.rmode_);
550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // V8_X87_ASSEMBLER_X87_INL_H_
555