1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright (c) 1994-2006 Sun Microsystems Inc.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// All Rights Reserved.
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met:
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - Redistributions of source code must retain the above copyright notice,
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// this list of conditions and the following disclaimer.
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - Redistribution in binary form must reproduce the above copyright
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer in the
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// documentation and/or other materials provided with the distribution.
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - Neither the name of Sun Microsystems or the names of contributors may
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// be used to endorse or promote products derived from this software without
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// specific prior written permission.
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The original source code covered by the above license above has been
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modified significantly by Google Inc.
333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A light-weight IA32 Assembler.
36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_IA32_ASSEMBLER_IA32_INL_H_
38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_IA32_ASSEMBLER_IA32_INL_H_
39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "ia32/assembler-ia32.h"
413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "cpu.h"
43f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#include "debug.h"
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The modes possibly affected by apply must be in kApplyMask.
50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RelocInfo::apply(intptr_t delta) {
51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (rmode_ == RUNTIME_ENTRY || IsCodeTarget(rmode_)) {
52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int32_t* p = reinterpret_cast<int32_t*>(pc_);
537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    *p -= delta;  // Relocate entry.
541e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    CPU::FlushICache(p, sizeof(uint32_t));
553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  } else if (rmode_ == JS_RETURN && IsPatchedReturnSequence()) {
56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Special handling of js_return when a break point is set (call
57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // instruction has been inserted).
58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1);
597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    *p -= delta;  // Relocate entry.
601e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    CPU::FlushICache(p, sizeof(uint32_t));
617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else if (rmode_ == DEBUG_BREAK_SLOT && IsPatchedDebugBreakSlotSequence()) {
627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    // Special handling of a debug break slot when a break point is set (call
637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    // instruction has been inserted).
647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1);
657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    *p -= delta;  // Relocate entry.
661e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    CPU::FlushICache(p, sizeof(uint32_t));
67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else if (IsInternalReference(rmode_)) {
68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // absolute code pointer inside code object moves with the code object.
69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int32_t* p = reinterpret_cast<int32_t*>(pc_);
707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    *p += delta;  // Relocate entry.
711e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    CPU::FlushICache(p, sizeof(uint32_t));
72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress RelocInfo::target_address() {
77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY);
78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Assembler::target_address_at(pc_);
79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress RelocInfo::target_address_address() {
833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY
843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                              || rmode_ == EMBEDDED_OBJECT
853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                              || rmode_ == EXTERNAL_REFERENCE);
86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return reinterpret_cast<Address>(pc_);
87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
90f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkeint RelocInfo::target_address_size() {
913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return Assembler::kSpecialTargetSize;
92f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke}
93f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
94f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid RelocInfo::set_target_address(Address target, WriteBarrierMode mode) {
9685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  Assembler::set_target_address_at(pc_, target);
973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY);
983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (mode == UPDATE_WRITE_BARRIER && host() != NULL && IsCodeTarget(rmode_)) {
993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Object* target_code = Code::GetCodeFromTargetAddress(target);
1003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(
1013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        host(), this, HeapObject::cast(target_code));
1023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject* RelocInfo::target_object() {
107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
1083ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  return Memory::Object_at(pc_);
1093ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
1103ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
1113ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
112d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockHandle<Object> RelocInfo::target_object_handle(Assembler* origin) {
1133ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
1143ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  return Memory::Object_Handle_at(pc_);
115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject** RelocInfo::target_object_address() {
119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
1203ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  return &Memory::Object_at(pc_);
121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid RelocInfo::set_target_object(Object* target, WriteBarrierMode mode) {
125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
1263ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  Memory::Object_at(pc_) = target;
1271e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  CPU::FlushICache(pc_, sizeof(Address));
1283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (mode == UPDATE_WRITE_BARRIER &&
1293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      host() != NULL &&
1303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      target->IsHeapObject()) {
1313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    host()->GetHeap()->incremental_marking()->RecordWrite(
1323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        host(), &Memory::Object_at(pc_), HeapObject::cast(target));
1333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress* RelocInfo::target_reference_address() {
138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(rmode_ == RelocInfo::EXTERNAL_REFERENCE);
139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return reinterpret_cast<Address*>(pc_);
140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
143b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochHandle<JSGlobalPropertyCell> RelocInfo::target_cell_handle() {
144b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL);
145b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Address address = Memory::Address_at(pc_);
146b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return Handle<JSGlobalPropertyCell>(
147b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      reinterpret_cast<JSGlobalPropertyCell**>(address));
148b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
149b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
150b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
151b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochJSGlobalPropertyCell* RelocInfo::target_cell() {
152b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL);
153b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Address address = Memory::Address_at(pc_);
154b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Object* object = HeapObject::FromAddress(
155b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      address - JSGlobalPropertyCell::kValueOffset);
156b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return reinterpret_cast<JSGlobalPropertyCell*>(object);
157b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
158b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
159b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid RelocInfo::set_target_cell(JSGlobalPropertyCell* cell,
1613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                WriteBarrierMode mode) {
162b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL);
163b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Address address = cell->address() + JSGlobalPropertyCell::kValueOffset;
164b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Memory::Address_at(pc_) = address;
1651e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  CPU::FlushICache(pc_, sizeof(Address));
1663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (mode == UPDATE_WRITE_BARRIER && host() != NULL) {
1673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // TODO(1550) We are passing NULL as a slot because cell can never be on
1683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // evacuation candidate.
1693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    host()->GetHeap()->incremental_marking()->RecordWrite(
1703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        host(), NULL, cell);
1713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
172b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
173b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
174b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress RelocInfo::call_address() {
176bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) ||
177bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch         (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Assembler::target_address_at(pc_ + 1);
179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RelocInfo::set_call_address(Address target) {
183bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) ||
184bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch         (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Assembler::set_target_address_at(pc_ + 1, target);
1863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (host() != NULL) {
1873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Object* target_code = Code::GetCodeFromTargetAddress(target);
1883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(
1893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        host(), this, HeapObject::cast(target_code));
1903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject* RelocInfo::call_object() {
195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return *call_object_address();
196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
199bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdochvoid RelocInfo::set_call_object(Object* target) {
200bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  *call_object_address() = target;
201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
204bb769b257e753aafcbd96767abb2abc645eaa20cBen MurdochObject** RelocInfo::call_object_address() {
205bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) ||
206bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch         (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
207bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  return reinterpret_cast<Object**>(pc_ + 1);
208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2113ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockbool RelocInfo::IsPatchedReturnSequence() {
212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return *pc_ == 0xE8;
213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2167f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochbool RelocInfo::IsPatchedDebugBreakSlotSequence() {
2177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  return !Assembler::IsNop(pc());
2187f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
2197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
2207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
221f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkevoid RelocInfo::Visit(ObjectVisitor* visitor) {
222f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  RelocInfo::Mode mode = rmode();
223f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  if (mode == RelocInfo::EMBEDDED_OBJECT) {
2243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    visitor->VisitEmbeddedPointer(this);
2251e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    CPU::FlushICache(pc_, sizeof(Address));
226f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  } else if (RelocInfo::IsCodeTarget(mode)) {
227f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    visitor->VisitCodeTarget(this);
228b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  } else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) {
229b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    visitor->VisitGlobalPropertyCell(this);
230f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  } else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
2313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    visitor->VisitExternalReference(this);
2321e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    CPU::FlushICache(pc_, sizeof(Address));
233f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#ifdef ENABLE_DEBUGGER_SUPPORT
23444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // TODO(isolates): Get a cached isolate below.
23544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  } else if (((RelocInfo::IsJSReturn(mode) &&
2367f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch              IsPatchedReturnSequence()) ||
2377f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch             (RelocInfo::IsDebugBreakSlot(mode) &&
23844f0eee88ff00398ff7f715fab053374d808c90dSteve Block              IsPatchedDebugBreakSlotSequence())) &&
23944f0eee88ff00398ff7f715fab053374d808c90dSteve Block             Isolate::Current()->debug()->has_break_points()) {
240f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    visitor->VisitDebugTarget(this);
241f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#endif
242f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  } else if (mode == RelocInfo::RUNTIME_ENTRY) {
243f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    visitor->VisitRuntimeEntry(this);
244f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  }
245f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke}
246f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
247f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
248756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merricktemplate<typename StaticVisitor>
24944f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid RelocInfo::Visit(Heap* heap) {
250756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  RelocInfo::Mode mode = rmode();
251756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  if (mode == RelocInfo::EMBEDDED_OBJECT) {
2523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    StaticVisitor::VisitEmbeddedPointer(heap, this);
2531e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    CPU::FlushICache(pc_, sizeof(Address));
254756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  } else if (RelocInfo::IsCodeTarget(mode)) {
2558b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    StaticVisitor::VisitCodeTarget(heap, this);
256b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  } else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) {
2578b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    StaticVisitor::VisitGlobalPropertyCell(heap, this);
258756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  } else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
2593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    StaticVisitor::VisitExternalReference(this);
2601e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    CPU::FlushICache(pc_, sizeof(Address));
261756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick#ifdef ENABLE_DEBUGGER_SUPPORT
26244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  } else if (heap->isolate()->debug()->has_break_points() &&
263756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick             ((RelocInfo::IsJSReturn(mode) &&
264756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick              IsPatchedReturnSequence()) ||
265756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick             (RelocInfo::IsDebugBreakSlot(mode) &&
266756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick              IsPatchedDebugBreakSlotSequence()))) {
2678b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    StaticVisitor::VisitDebugTarget(heap, this);
268756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick#endif
269756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  } else if (mode == RelocInfo::RUNTIME_ENTRY) {
270756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    StaticVisitor::VisitRuntimeEntry(this);
271756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  }
272756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick}
273756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
274756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
275756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockImmediate::Immediate(int x)  {
277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  x_ = x;
278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  rmode_ = RelocInfo::NONE;
279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockImmediate::Immediate(const ExternalReference& ext) {
283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  x_ = reinterpret_cast<int32_t>(ext.address());
284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  rmode_ = RelocInfo::EXTERNAL_REFERENCE;
285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockImmediate::Immediate(Label* internal_offset) {
289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  x_ = reinterpret_cast<int32_t>(internal_offset);
290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  rmode_ = RelocInfo::INTERNAL_REFERENCE;
291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockImmediate::Immediate(Handle<Object> handle) {
295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Verify all Objects referred by code are NOT in new space.
296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* obj = *handle;
29744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(!HEAP->InNewSpace(obj));
298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (obj->IsHeapObject()) {
299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    x_ = reinterpret_cast<intptr_t>(handle.location());
300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    rmode_ = RelocInfo::EMBEDDED_OBJECT;
301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // no relocation needed
303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    x_ =  reinterpret_cast<intptr_t>(obj);
304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    rmode_ = RelocInfo::NONE;
305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockImmediate::Immediate(Smi* value) {
310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  x_ = reinterpret_cast<intptr_t>(value);
311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  rmode_ = RelocInfo::NONE;
312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
315b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochImmediate::Immediate(Address addr) {
316b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  x_ = reinterpret_cast<int32_t>(addr);
317b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  rmode_ = RelocInfo::NONE;
318b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
319b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
320b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit(uint32_t x) {
322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  *reinterpret_cast<uint32_t*>(pc_) = x;
323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  pc_ += sizeof(uint32_t);
324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit(Handle<Object> handle) {
328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Verify all Objects referred by code are NOT in new space.
329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* obj = *handle;
33044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(!isolate()->heap()->InNewSpace(obj));
331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (obj->IsHeapObject()) {
332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    emit(reinterpret_cast<intptr_t>(handle.location()),
333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block         RelocInfo::EMBEDDED_OBJECT);
334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // no relocation needed
336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    emit(reinterpret_cast<intptr_t>(obj));
337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
341257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid Assembler::emit(uint32_t x, RelocInfo::Mode rmode, unsigned id) {
342257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (rmode == RelocInfo::CODE_TARGET && id != kNoASTId) {
343257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    RecordRelocInfo(RelocInfo::CODE_TARGET_WITH_ID, static_cast<intptr_t>(id));
344257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  } else if (rmode != RelocInfo::NONE) {
345257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    RecordRelocInfo(rmode);
346257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  emit(x);
348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit(const Immediate& x) {
352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (x.rmode_ == RelocInfo::INTERNAL_REFERENCE) {
353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Label* label = reinterpret_cast<Label*>(x.x_);
354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    emit_code_relative_offset(label);
355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return;
356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (x.rmode_ != RelocInfo::NONE) RecordRelocInfo(x.rmode_);
358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  emit(x.x_);
359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_code_relative_offset(Label* label) {
363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (label->is_bound()) {
364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int32_t pos;
365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    pos = label->pos() + Code::kHeaderSize - kHeapObjectTag;
366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    emit(pos);
367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    emit_disp(label, Displacement::CODE_RELATIVE);
369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_w(const Immediate& x) {
374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(x.rmode_ == RelocInfo::NONE);
375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  uint16_t value = static_cast<uint16_t>(x.x_);
376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  reinterpret_cast<uint16_t*>(pc_)[0] = value;
377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  pc_ += sizeof(uint16_t);
378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress Assembler::target_address_at(Address pc) {
382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return pc + sizeof(int32_t) + *reinterpret_cast<int32_t*>(pc);
383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::set_target_address_at(Address pc, Address target) {
387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int32_t* p = reinterpret_cast<int32_t*>(pc);
388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  *p = target - (pc + sizeof(int32_t));
389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CPU::FlushICache(p, sizeof(int32_t));
390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockDisplacement Assembler::disp_at(Label* L) {
394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Displacement(long_at(L->pos()));
395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::disp_at_put(Label* L, Displacement disp) {
399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  long_at_put(L->pos(), disp.data());
400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_disp(Label* L, Displacement::Type type) {
404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Displacement disp(L, type);
405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  L->link_to(pc_offset());
406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  emit(static_cast<int>(disp.data()));
407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
410257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid Assembler::emit_near_disp(Label* L) {
411257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  byte disp = 0x00;
412257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (L->is_near_linked()) {
413257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    int offset = L->near_link_pos() - pc_offset();
414257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    ASSERT(is_int8(offset));
415257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    disp = static_cast<byte>(offset & 0xFF);
416257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
417257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  L->link_to(pc_offset(), Label::kNear);
418257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  *pc_++ = disp;
419257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
420257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
421257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Operand::set_modrm(int mod, Register rm) {
423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT((mod & -4) == 0);
424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  buf_[0] = mod << 6 | rm.code();
425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  len_ = 1;
426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Operand::set_sib(ScaleFactor scale, Register index, Register base) {
430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(len_ == 1);
431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT((scale & -4) == 0);
432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Use SIB with no index register only for base esp.
433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(!index.is(esp) || base.is(esp));
434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  buf_[1] = scale << 6 | index.code() << 3 | base.code();
435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  len_ = 2;
436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Operand::set_disp8(int8_t disp) {
440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(len_ == 1 || len_ == 2);
441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  *reinterpret_cast<int8_t*>(&buf_[len_++]) = disp;
442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Operand::set_dispr(int32_t disp, RelocInfo::Mode rmode) {
446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(len_ == 1 || len_ == 2);
447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int32_t* p = reinterpret_cast<int32_t*>(&buf_[len_]);
448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  *p = disp;
449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  len_ += sizeof(int32_t);
450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  rmode_ = rmode;
451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockOperand::Operand(Register reg) {
454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // reg
455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  set_modrm(3, reg);
456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4596ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockOperand::Operand(XMMRegister xmm_reg) {
4606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Register reg = { xmm_reg.code() };
4616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  set_modrm(3, reg);
4626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
4636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
4646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockOperand::Operand(int32_t disp, RelocInfo::Mode rmode) {
466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [disp/r]
467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  set_modrm(0, ebp);
468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  set_dispr(disp, rmode);
469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif  // V8_IA32_ASSEMBLER_IA32_INL_H_
474