1e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// Copyright 2011 the V8 project authors. All rights reserved.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met:
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions of source code must retain the above copyright
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       notice, this list of conditions and the following disclaimer.
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions in binary form must reproduce the above
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       copyright notice, this list of conditions and the following
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       disclaimer in the documentation and/or other materials provided
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       with the distribution.
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Neither the name of Google Inc. nor the names of its
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       contributors may be used to endorse or promote products derived
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       from this software without specific prior written permission.
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_X64_ASSEMBLER_X64_INL_H_
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_X64_ASSEMBLER_X64_INL_H_
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "cpu.h"
32f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#include "debug.h"
3344f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "v8memory.h"
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// -----------------------------------------------------------------------------
40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Implementation of Assembler
41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emitl(uint32_t x) {
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Memory::uint32_at(pc_) = x;
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  pc_ += sizeof(uint32_t);
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emitq(uint64_t x, RelocInfo::Mode rmode) {
50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Memory::uint64_at(pc_) = x;
51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (rmode != RelocInfo::NONE) {
52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    RecordRelocInfo(rmode, x);
53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  pc_ += sizeof(uint64_t);
55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emitw(uint16_t x) {
59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Memory::uint16_at(pc_) = x;
60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  pc_ += sizeof(uint16_t);
61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
643ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid Assembler::emit_code_target(Handle<Code> target, RelocInfo::Mode rmode) {
653ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  ASSERT(RelocInfo::IsCodeTarget(rmode));
663ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  RecordRelocInfo(rmode);
673ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  int current = code_targets_.length();
683ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  if (current > 0 && code_targets_.last().is_identical_to(target)) {
693ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    // Optimization if we keep jumping to the same code target.
703ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    emitl(current - 1);
713ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  } else {
723ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    code_targets_.Add(target);
733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    emitl(current);
743ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_rex_64(Register reg, Register rm_reg) {
79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  emit(0x48 | reg.high_bit() << 2 | rm_reg.high_bit());
80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_rex_64(XMMRegister reg, Register rm_reg) {
84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  emit(0x48 | (reg.code() & 0x8) >> 1 | rm_reg.code() >> 3);
85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
886ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid Assembler::emit_rex_64(Register reg, XMMRegister rm_reg) {
896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  emit(0x48 | (reg.code() & 0x8) >> 1 | rm_reg.code() >> 3);
906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_rex_64(Register reg, const Operand& op) {
94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  emit(0x48 | reg.high_bit() << 2 | op.rex_);
95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_rex_64(XMMRegister reg, const Operand& op) {
99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  emit(0x48 | (reg.code() & 0x8) >> 1 | op.rex_);
100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_rex_64(Register rm_reg) {
104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT_EQ(rm_reg.code() & 0xf, rm_reg.code());
105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  emit(0x48 | rm_reg.high_bit());
106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_rex_64(const Operand& op) {
110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  emit(0x48 | op.rex_);
111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_rex_32(Register reg, Register rm_reg) {
115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  emit(0x40 | reg.high_bit() << 2 | rm_reg.high_bit());
116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_rex_32(Register reg, const Operand& op) {
120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  emit(0x40 | reg.high_bit() << 2  | op.rex_);
121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_rex_32(Register rm_reg) {
125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  emit(0x40 | rm_reg.high_bit());
126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_rex_32(const Operand& op) {
130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  emit(0x40 | op.rex_);
131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_optional_rex_32(Register reg, Register rm_reg) {
135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  byte rex_bits = reg.high_bit() << 2 | rm_reg.high_bit();
136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (rex_bits != 0) emit(0x40 | rex_bits);
137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_optional_rex_32(Register reg, const Operand& op) {
141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  byte rex_bits =  reg.high_bit() << 2 | op.rex_;
142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (rex_bits != 0) emit(0x40 | rex_bits);
143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_optional_rex_32(XMMRegister reg, const Operand& op) {
147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  byte rex_bits =  (reg.code() & 0x8) >> 1 | op.rex_;
148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (rex_bits != 0) emit(0x40 | rex_bits);
149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_optional_rex_32(XMMRegister reg, XMMRegister base) {
153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  byte rex_bits =  (reg.code() & 0x8) >> 1 | (base.code() & 0x8) >> 3;
154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (rex_bits != 0) emit(0x40 | rex_bits);
155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_optional_rex_32(XMMRegister reg, Register base) {
159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  byte rex_bits =  (reg.code() & 0x8) >> 1 | (base.code() & 0x8) >> 3;
160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (rex_bits != 0) emit(0x40 | rex_bits);
161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1646ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid Assembler::emit_optional_rex_32(Register reg, XMMRegister base) {
1656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  byte rex_bits =  (reg.code() & 0x8) >> 1 | (base.code() & 0x8) >> 3;
1666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (rex_bits != 0) emit(0x40 | rex_bits);
1676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
1686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_optional_rex_32(Register rm_reg) {
171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (rm_reg.high_bit()) emit(0x41);
172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_optional_rex_32(const Operand& op) {
176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (op.rex_ != 0) emit(0x40 | op.rex_);
177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress Assembler::target_address_at(Address pc) {
1813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  return Memory::int32_at(pc) + pc + 4;
182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::set_target_address_at(Address pc, Address target) {
186d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Memory::int32_at(pc) = static_cast<int32_t>(target - pc - 4);
1873ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  CPU::FlushICache(pc, sizeof(int32_t));
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1903ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockHandle<Object> Assembler::code_target_object_handle_at(Address pc) {
1913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  return code_targets_[Memory::int32_at(pc)];
1923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// -----------------------------------------------------------------------------
195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Implementation of RelocInfo
196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The modes possibly affected by apply must be in kApplyMask.
198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RelocInfo::apply(intptr_t delta) {
199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (IsInternalReference(rmode_)) {
200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // absolute code pointer inside code object moves with the code object.
201d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    Memory::Address_at(pc_) += static_cast<int32_t>(delta);
2021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    CPU::FlushICache(pc_, sizeof(Address));
2033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  } else if (IsCodeTarget(rmode_)) {
204d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    Memory::int32_at(pc_) -= static_cast<int32_t>(delta);
2051e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    CPU::FlushICache(pc_, sizeof(int32_t));
206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress RelocInfo::target_address() {
211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY);
2123ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  if (IsCodeTarget(rmode_)) {
2133ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    return Assembler::target_address_at(pc_);
2143ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  } else {
2153ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    return Memory::Address_at(pc_);
2163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress RelocInfo::target_address_address() {
221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY);
222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return reinterpret_cast<Address>(pc_);
223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
226f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkeint RelocInfo::target_address_size() {
227f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  if (IsCodedSpecially()) {
228f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    return Assembler::kCallTargetSize;
229f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  } else {
230f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    return Assembler::kExternalTargetSize;
231f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  }
232f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke}
233f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
234f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RelocInfo::set_target_address(Address target) {
236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY);
2373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  if (IsCodeTarget(rmode_)) {
2383ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    Assembler::set_target_address_at(pc_, target);
2393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  } else {
2403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    Memory::Address_at(pc_) = target;
2411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    CPU::FlushICache(pc_, sizeof(Address));
2423ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject* RelocInfo::target_object() {
247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
2483ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  return Memory::Object_at(pc_);
2493ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
2503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
2513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
2523ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockHandle<Object> RelocInfo::target_object_handle(Assembler *origin) {
2533ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
2543ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  if (rmode_ == EMBEDDED_OBJECT) {
2553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    return Memory::Object_Handle_at(pc_);
2563ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  } else {
2573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    return origin->code_target_object_handle_at(pc_);
2583ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject** RelocInfo::target_object_address() {
263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return reinterpret_cast<Object**>(pc_);
265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress* RelocInfo::target_reference_address() {
269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(rmode_ == RelocInfo::EXTERNAL_REFERENCE);
270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return reinterpret_cast<Address*>(pc_);
271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RelocInfo::set_target_object(Object* target) {
275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  *reinterpret_cast<Object**>(pc_) = target;
2771e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  CPU::FlushICache(pc_, sizeof(Address));
278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
281b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochHandle<JSGlobalPropertyCell> RelocInfo::target_cell_handle() {
282b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL);
283b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Address address = Memory::Address_at(pc_);
284b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return Handle<JSGlobalPropertyCell>(
285b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      reinterpret_cast<JSGlobalPropertyCell**>(address));
286b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
287b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
288b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
289b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochJSGlobalPropertyCell* RelocInfo::target_cell() {
290b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL);
291b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Address address = Memory::Address_at(pc_);
292b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Object* object = HeapObject::FromAddress(
293b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      address - JSGlobalPropertyCell::kValueOffset);
294b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return reinterpret_cast<JSGlobalPropertyCell*>(object);
295b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
296b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
297b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
298b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid RelocInfo::set_target_cell(JSGlobalPropertyCell* cell) {
299b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL);
300b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Address address = cell->address() + JSGlobalPropertyCell::kValueOffset;
301b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Memory::Address_at(pc_) = address;
3021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  CPU::FlushICache(pc_, sizeof(Address));
303b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
304b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
305b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3063ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockbool RelocInfo::IsPatchedReturnSequence() {
307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The recognized call sequence is:
308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  //  movq(kScratchRegister, immediate64); call(kScratchRegister);
309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // It only needs to be distinguished from a return sequence
310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  //  movq(rsp, rbp); pop(rbp); ret(n); int3 *6
311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The 11th byte is int3 (0xCC) in the return sequence and
312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // REX.WB (0x48+register bit) for the call sequence.
3133ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block#ifdef ENABLE_DEBUGGER_SUPPORT
314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return pc_[10] != 0xCC;
3153ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block#else
3163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  return false;
3173ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block#endif
318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochbool RelocInfo::IsPatchedDebugBreakSlotSequence() {
3227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  return !Assembler::IsNop(pc());
3237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
3247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
3257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress RelocInfo::call_address() {
327bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) ||
328bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch         (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
3293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  return Memory::Address_at(
3303ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block      pc_ + Assembler::kRealPatchReturnSequenceAddressOffset);
331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RelocInfo::set_call_address(Address target) {
335bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) ||
336bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch         (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
3373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  Memory::Address_at(pc_ + Assembler::kRealPatchReturnSequenceAddressOffset) =
3383ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block      target;
3391e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  CPU::FlushICache(pc_ + Assembler::kRealPatchReturnSequenceAddressOffset,
3401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block                   sizeof(Address));
341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject* RelocInfo::call_object() {
345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return *call_object_address();
346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RelocInfo::set_call_object(Object* target) {
350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  *call_object_address() = target;
351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject** RelocInfo::call_object_address() {
355bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) ||
356bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch         (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return reinterpret_cast<Object**>(
358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      pc_ + Assembler::kPatchReturnSequenceAddressOffset);
359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
361f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
362f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkevoid RelocInfo::Visit(ObjectVisitor* visitor) {
363f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  RelocInfo::Mode mode = rmode();
364f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  if (mode == RelocInfo::EMBEDDED_OBJECT) {
365f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    visitor->VisitPointer(target_object_address());
3661e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    CPU::FlushICache(pc_, sizeof(Address));
367f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  } else if (RelocInfo::IsCodeTarget(mode)) {
368f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    visitor->VisitCodeTarget(this);
3691e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  } else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) {
3701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    visitor->VisitGlobalPropertyCell(this);
371f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  } else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
372f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    visitor->VisitExternalReference(target_reference_address());
3731e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    CPU::FlushICache(pc_, sizeof(Address));
374f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#ifdef ENABLE_DEBUGGER_SUPPORT
37544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // TODO(isolates): Get a cached isolate below.
37644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  } else if (((RelocInfo::IsJSReturn(mode) &&
3777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch              IsPatchedReturnSequence()) ||
3787f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch             (RelocInfo::IsDebugBreakSlot(mode) &&
37944f0eee88ff00398ff7f715fab053374d808c90dSteve Block              IsPatchedDebugBreakSlotSequence())) &&
38044f0eee88ff00398ff7f715fab053374d808c90dSteve Block             Isolate::Current()->debug()->has_break_points()) {
381f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    visitor->VisitDebugTarget(this);
382f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#endif
383f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  } else if (mode == RelocInfo::RUNTIME_ENTRY) {
384f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    visitor->VisitRuntimeEntry(this);
385f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  }
386f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke}
387f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
388f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
389756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merricktemplate<typename StaticVisitor>
39044f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid RelocInfo::Visit(Heap* heap) {
391756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  RelocInfo::Mode mode = rmode();
392756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  if (mode == RelocInfo::EMBEDDED_OBJECT) {
39344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    StaticVisitor::VisitPointer(heap, target_object_address());
3941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    CPU::FlushICache(pc_, sizeof(Address));
395756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  } else if (RelocInfo::IsCodeTarget(mode)) {
3968b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    StaticVisitor::VisitCodeTarget(heap, this);
3971e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  } else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) {
3988b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    StaticVisitor::VisitGlobalPropertyCell(heap, this);
399756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  } else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
400756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    StaticVisitor::VisitExternalReference(target_reference_address());
4011e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    CPU::FlushICache(pc_, sizeof(Address));
402756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick#ifdef ENABLE_DEBUGGER_SUPPORT
40344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  } else if (heap->isolate()->debug()->has_break_points() &&
404756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick             ((RelocInfo::IsJSReturn(mode) &&
405756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick              IsPatchedReturnSequence()) ||
406756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick             (RelocInfo::IsDebugBreakSlot(mode) &&
407756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick              IsPatchedDebugBreakSlotSequence()))) {
4088b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    StaticVisitor::VisitDebugTarget(heap, this);
409756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick#endif
410756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  } else if (mode == RelocInfo::RUNTIME_ENTRY) {
411756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    StaticVisitor::VisitRuntimeEntry(this);
412756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  }
413756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick}
414756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
415756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// -----------------------------------------------------------------------------
417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Implementation of Operand
418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Operand::set_modrm(int mod, Register rm_reg) {
420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(is_uint2(mod));
421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  buf_[0] = mod << 6 | rm_reg.low_bits();
422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Set REX.B to the high bit of rm.code().
423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  rex_ |= rm_reg.high_bit();
424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Operand::set_sib(ScaleFactor scale, Register index, Register base) {
428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(len_ == 1);
429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(is_uint2(scale));
430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Use SIB with no index register only for base rsp or r12. Otherwise we
431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // would skip the SIB byte entirely.
432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(!index.is(rsp) || base.is(rsp) || base.is(r12));
4331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  buf_[1] = (scale << 6) | (index.low_bits() << 3) | base.low_bits();
434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  rex_ |= index.high_bit() << 1 | base.high_bit();
435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  len_ = 2;
436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Operand::set_disp8(int disp) {
439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(is_int8(disp));
440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(len_ == 1 || len_ == 2);
441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int8_t* p = reinterpret_cast<int8_t*>(&buf_[len_]);
442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  *p = disp;
443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  len_ += sizeof(int8_t);
444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Operand::set_disp32(int disp) {
447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(len_ == 1 || len_ == 2);
448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int32_t* p = reinterpret_cast<int32_t*>(&buf_[len_]);
449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  *p = disp;
450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  len_ += sizeof(int32_t);
451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif  // V8_X64_ASSEMBLER_X64_INL_H_
457