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