13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_X64_ASSEMBLER_X64_INL_H_ 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_X64_ASSEMBLER_X64_INL_H_ 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/x64/assembler-x64.h" 93ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/cpu.h" 11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/debug/debug.h" 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/v8memory.h" 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool CpuFeatures::SupportsCrankshaft() { return true; } 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 19f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochbool CpuFeatures::SupportsSimd128() { return false; } 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------- 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Implementation of Assembler 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const byte kCallOpcode = 0xE8; 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// The length of pushq(rbp), movp(rbp, rsp), Push(rsi) and Push(rdi). 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const int kNoCodeAgeSequenceLength = kPointerSize == kInt64Size ? 6 : 17; 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emitl(uint32_t x) { 31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Memory::uint32_at(pc_) = x; 32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pc_ += sizeof(uint32_t); 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::emitp(void* x, RelocInfo::Mode rmode) { 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uintptr_t value = reinterpret_cast<uintptr_t>(x); 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Memory::uintptr_at(pc_) = value; 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!RelocInfo::IsNone(rmode)) { 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RecordRelocInfo(rmode, value); 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pc_ += sizeof(uintptr_t); 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::emitq(uint64_t x) { 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Memory::uint64_at(pc_) = x; 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pc_ += sizeof(uint64_t); 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emitw(uint16_t x) { 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Memory::uint16_at(pc_) = x; 54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pc_ += sizeof(uint16_t); 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 58257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid Assembler::emit_code_target(Handle<Code> target, 59257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch RelocInfo::Mode rmode, 60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TypeFeedbackId ast_id) { 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(RelocInfo::IsCodeTarget(rmode) || 62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch rmode == RelocInfo::CODE_AGE_SEQUENCE); 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (rmode == RelocInfo::CODE_TARGET && !ast_id.IsNone()) { 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RecordRelocInfo(RelocInfo::CODE_TARGET_WITH_ID, ast_id.ToInt()); 65257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 66257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch RecordRelocInfo(rmode); 67257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 683ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int current = code_targets_.length(); 69f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (current > 0 && code_targets_.last().address() == target.address()) { 703ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Optimization if we keep jumping to the same code target. 713ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block emitl(current - 1); 723ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block code_targets_.Add(target); 743ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block emitl(current); 753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 783ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::emit_runtime_entry(Address entry, RelocInfo::Mode rmode) { 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(RelocInfo::IsRuntimeEntry(rmode)); 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RecordRelocInfo(rmode); 82bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch emitl(static_cast<uint32_t>( 83bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch entry - isolate()->heap()->memory_allocator()->code_range()->start())); 84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_rex_64(Register reg, Register rm_reg) { 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(0x48 | reg.high_bit() << 2 | rm_reg.high_bit()); 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_rex_64(XMMRegister reg, Register rm_reg) { 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(0x48 | (reg.code() & 0x8) >> 1 | rm_reg.code() >> 3); 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 976ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid Assembler::emit_rex_64(Register reg, XMMRegister rm_reg) { 986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block emit(0x48 | (reg.code() & 0x8) >> 1 | rm_reg.code() >> 3); 996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 1006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_rex_64(Register reg, const Operand& op) { 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(0x48 | reg.high_bit() << 2 | op.rex_); 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_rex_64(XMMRegister reg, const Operand& op) { 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(0x48 | (reg.code() & 0x8) >> 1 | op.rex_); 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_rex_64(Register rm_reg) { 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(rm_reg.code() & 0xf, rm_reg.code()); 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(0x48 | rm_reg.high_bit()); 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_rex_64(const Operand& op) { 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(0x48 | op.rex_); 120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_rex_32(Register reg, Register rm_reg) { 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(0x40 | reg.high_bit() << 2 | rm_reg.high_bit()); 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_rex_32(Register reg, const Operand& op) { 129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(0x40 | reg.high_bit() << 2 | op.rex_); 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_rex_32(Register rm_reg) { 134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(0x40 | rm_reg.high_bit()); 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_rex_32(const Operand& op) { 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(0x40 | op.rex_); 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_optional_rex_32(Register reg, Register rm_reg) { 144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte rex_bits = reg.high_bit() << 2 | rm_reg.high_bit(); 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (rex_bits != 0) emit(0x40 | rex_bits); 146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_optional_rex_32(Register reg, const Operand& op) { 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte rex_bits = reg.high_bit() << 2 | op.rex_; 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (rex_bits != 0) emit(0x40 | rex_bits); 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_optional_rex_32(XMMRegister reg, const Operand& op) { 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte rex_bits = (reg.code() & 0x8) >> 1 | op.rex_; 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (rex_bits != 0) emit(0x40 | rex_bits); 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_optional_rex_32(XMMRegister reg, XMMRegister base) { 162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte rex_bits = (reg.code() & 0x8) >> 1 | (base.code() & 0x8) >> 3; 163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (rex_bits != 0) emit(0x40 | rex_bits); 164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_optional_rex_32(XMMRegister reg, Register base) { 168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte rex_bits = (reg.code() & 0x8) >> 1 | (base.code() & 0x8) >> 3; 169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (rex_bits != 0) emit(0x40 | rex_bits); 170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1736ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid Assembler::emit_optional_rex_32(Register reg, XMMRegister base) { 1746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block byte rex_bits = (reg.code() & 0x8) >> 1 | (base.code() & 0x8) >> 3; 1756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (rex_bits != 0) emit(0x40 | rex_bits); 1766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 1776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_optional_rex_32(Register rm_reg) { 180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (rm_reg.high_bit()) emit(0x41); 181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 183958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Assembler::emit_optional_rex_32(XMMRegister rm_reg) { 184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (rm_reg.high_bit()) emit(0x41); 185958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_optional_rex_32(const Operand& op) { 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (op.rex_ != 0) emit(0x40 | op.rex_); 189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 192958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// byte 1 of 3-byte VEX 193958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Assembler::emit_vex3_byte1(XMMRegister reg, XMMRegister rm, 194958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LeadingOpcode m) { 195958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier byte rxb = ~((reg.high_bit() << 2) | rm.high_bit()) << 5; 196958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier emit(rxb | m); 197958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 198958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 199958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 200958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// byte 1 of 3-byte VEX 201958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Assembler::emit_vex3_byte1(XMMRegister reg, const Operand& rm, 202958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LeadingOpcode m) { 203958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier byte rxb = ~((reg.high_bit() << 2) | rm.rex_) << 5; 204958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier emit(rxb | m); 205958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 206958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 207958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 208958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// byte 1 of 2-byte VEX 209958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Assembler::emit_vex2_byte1(XMMRegister reg, XMMRegister v, VectorLength l, 210958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SIMDPrefix pp) { 211958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier byte rv = ~((reg.high_bit() << 4) | v.code()) << 3; 212958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier emit(rv | l | pp); 213958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 214958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 215958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 216958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// byte 2 of 3-byte VEX 217958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Assembler::emit_vex3_byte2(VexW w, XMMRegister v, VectorLength l, 218958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SIMDPrefix pp) { 219958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier emit(w | ((~v.code() & 0xf) << 3) | l | pp); 220958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 221958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 222958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 223958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Assembler::emit_vex_prefix(XMMRegister reg, XMMRegister vreg, 224958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier XMMRegister rm, VectorLength l, SIMDPrefix pp, 225958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LeadingOpcode mm, VexW w) { 226958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (rm.high_bit() || mm != k0F || w != kW0) { 227958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier emit_vex3_byte0(); 228958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier emit_vex3_byte1(reg, rm, mm); 229958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier emit_vex3_byte2(w, vreg, l, pp); 230958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 231958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier emit_vex2_byte0(); 232958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier emit_vex2_byte1(reg, vreg, l, pp); 233958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 234958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 235958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 236958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::emit_vex_prefix(Register reg, Register vreg, Register rm, 238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VectorLength l, SIMDPrefix pp, LeadingOpcode mm, 239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VexW w) { 240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch XMMRegister ireg = {reg.code()}; 241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch XMMRegister ivreg = {vreg.code()}; 242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch XMMRegister irm = {rm.code()}; 243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch emit_vex_prefix(ireg, ivreg, irm, l, pp, mm, w); 244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 247958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Assembler::emit_vex_prefix(XMMRegister reg, XMMRegister vreg, 248958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const Operand& rm, VectorLength l, 249958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SIMDPrefix pp, LeadingOpcode mm, VexW w) { 250958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (rm.rex_ || mm != k0F || w != kW0) { 251958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier emit_vex3_byte0(); 252958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier emit_vex3_byte1(reg, rm, mm); 253958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier emit_vex3_byte2(w, vreg, l, pp); 254958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 255958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier emit_vex2_byte0(); 256958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier emit_vex2_byte1(reg, vreg, l, pp); 257958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 258958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 259958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 260958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::emit_vex_prefix(Register reg, Register vreg, const Operand& rm, 262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VectorLength l, SIMDPrefix pp, LeadingOpcode mm, 263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VexW w) { 264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch XMMRegister ireg = {reg.code()}; 265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch XMMRegister ivreg = {vreg.code()}; 266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch emit_vex_prefix(ireg, ivreg, rm, l, pp, mm, w); 267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAddress Assembler::target_address_at(Address pc, Address constant_pool) { 2713ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return Memory::int32_at(pc) + pc + 4; 272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::set_target_address_at(Isolate* isolate, Address pc, 276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address constant_pool, Address target, 277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ICacheFlushMode icache_flush_mode) { 278d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Memory::int32_at(pc) = static_cast<int32_t>(target - pc - 4); 279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (icache_flush_mode != SKIP_ICACHE_FLUSH) { 280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Assembler::FlushICache(isolate, pc, sizeof(int32_t)); 281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::deserialization_set_target_internal_reference_at( 286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate, Address pc, Address target, RelocInfo::Mode mode) { 287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Memory::Address_at(pc) = target; 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAddress Assembler::target_address_from_return_address(Address pc) { 292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return pc - kCallTargetAddressOffset; 293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockHandle<Object> Assembler::code_target_object_handle_at(Address pc) { 2973ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return code_targets_[Memory::int32_at(pc)]; 2983ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAddress Assembler::runtime_entry_at(Address pc) { 302bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return Memory::int32_at(pc) + 303bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch isolate()->heap()->memory_allocator()->code_range()->start(); 304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------- 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Implementation of RelocInfo 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The modes possibly affected by apply must be in kApplyMask. 310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid RelocInfo::apply(intptr_t delta) { 311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)) { 312d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Memory::int32_at(pc_) -= static_cast<int32_t>(delta); 313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (IsCodeAgeSequence(rmode_)) { 314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (*pc_ == kCallOpcode) { 315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1); 316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *p -= static_cast<int32_t>(delta); // Relocate entry. 317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (IsInternalReference(rmode_)) { 319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // absolute code pointer inside code object moves with the code object. 320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Memory::Address_at(pc_) += delta; 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress RelocInfo::target_address() { 326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); 327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Assembler::target_address_at(pc_, host_); 328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress RelocInfo::target_address_address() { 331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) 3323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch || rmode_ == EMBEDDED_OBJECT 3333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch || rmode_ == EXTERNAL_REFERENCE); 334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return reinterpret_cast<Address>(pc_); 335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAddress RelocInfo::constant_pool_entry_address() { 339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 344f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkeint RelocInfo::target_address_size() { 345f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke if (IsCodedSpecially()) { 3463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return Assembler::kSpecialTargetSize; 347f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke } else { 3483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return kPointerSize; 349f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke } 350f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke} 351f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 352f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject* RelocInfo::target_object() { 354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 3553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return Memory::Object_at(pc_); 3563ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 3573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 3583ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 3593ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Object> RelocInfo::target_object_handle(Assembler* origin) { 360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 3613ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (rmode_ == EMBEDDED_OBJECT) { 3623ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return Memory::Object_Handle_at(pc_); 3633ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 3643ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return origin->code_target_object_handle_at(pc_); 3653ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAddress RelocInfo::target_external_reference() { 370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rmode_ == RelocInfo::EXTERNAL_REFERENCE); 371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Memory::Address_at(pc_); 372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAddress RelocInfo::target_internal_reference() { 376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(rmode_ == INTERNAL_REFERENCE); 377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Memory::Address_at(pc_); 378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAddress RelocInfo::target_internal_reference_address() { 382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(rmode_ == INTERNAL_REFERENCE); 383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return reinterpret_cast<Address>(pc_); 384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RelocInfo::set_target_object(Object* target, 388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch WriteBarrierMode write_barrier_mode, 389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ICacheFlushMode icache_flush_mode) { 390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 3913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Memory::Object_at(pc_) = target; 392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (icache_flush_mode != SKIP_ICACHE_FLUSH) { 393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Assembler::FlushICache(isolate_, pc_, sizeof(Address)); 394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (write_barrier_mode == UPDATE_WRITE_BARRIER && 3963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch host() != NULL && 3973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch target->IsHeapObject()) { 3983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( 3993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch host(), this, HeapObject::cast(target)); 400f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch host()->GetHeap()->RecordWriteIntoCode(host(), this, target); 4013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAddress RelocInfo::target_runtime_entry(Assembler* origin) { 406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsRuntimeEntry(rmode_)); 407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return origin->runtime_entry_at(pc_); 408b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 409b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 410b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RelocInfo::set_target_runtime_entry(Address target, 412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch WriteBarrierMode write_barrier_mode, 413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ICacheFlushMode icache_flush_mode) { 414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsRuntimeEntry(rmode_)); 415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (target_address() != target) { 416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_target_address(target, write_barrier_mode, icache_flush_mode); 417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Cell> RelocInfo::target_cell_handle() { 422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rmode_ == RelocInfo::CELL); 423b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Address address = Memory::Address_at(pc_); 424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Handle<Cell>(reinterpret_cast<Cell**>(address)); 425b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 426b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 427b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochCell* RelocInfo::target_cell() { 429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rmode_ == RelocInfo::CELL); 430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Cell::FromValueAddress(Memory::Address_at(pc_)); 431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RelocInfo::set_target_cell(Cell* cell, 435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch WriteBarrierMode write_barrier_mode, 436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ICacheFlushMode icache_flush_mode) { 437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rmode_ == RelocInfo::CELL); 438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address address = cell->address() + Cell::kValueOffset; 439b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Memory::Address_at(pc_) = address; 440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (icache_flush_mode != SKIP_ICACHE_FLUSH) { 441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Assembler::FlushICache(isolate_, pc_, sizeof(Address)); 442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (write_barrier_mode == UPDATE_WRITE_BARRIER && 4443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch host() != NULL) { 445109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(host(), this, 446109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch cell); 4473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 448b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 449b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 450b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RelocInfo::WipeOut() { 452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsEmbeddedObject(rmode_) || IsExternalReference(rmode_) || 453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IsInternalReference(rmode_)) { 454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Memory::Address_at(pc_) = NULL; 455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)) { 456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Effectively write zero into the relocation. 457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Assembler::set_target_address_at(isolate_, pc_, host_, 458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pc_ + sizeof(int32_t)); 459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Object> RelocInfo::code_age_stub_handle(Assembler* origin) { 466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); 467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(*pc_ == kCallOpcode); 468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return origin->code_target_object_handle_at(pc_ + 1); 469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochCode* RelocInfo::code_age_stub() { 473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); 474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(*pc_ == kCallOpcode); 475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Code::GetCodeFromTargetAddress( 476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler::target_address_at(pc_ + 1, host_)); 477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RelocInfo::set_code_age_stub(Code* stub, 481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ICacheFlushMode icache_flush_mode) { 482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(*pc_ == kCallOpcode); 483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); 484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Assembler::set_target_address_at( 485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate_, pc_ + 1, host_, stub->instruction_start(), icache_flush_mode); 486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAddress RelocInfo::debug_call_address() { 490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()); 491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Memory::Address_at(pc_ + Assembler::kPatchDebugBreakSlotAddressOffset); 492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid RelocInfo::set_debug_call_address(Address target) { 496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()); 497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Memory::Address_at(pc_ + Assembler::kPatchDebugBreakSlotAddressOffset) = 4983ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block target; 499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Assembler::FlushICache(isolate_, 500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pc_ + Assembler::kPatchDebugBreakSlotAddressOffset, 501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch sizeof(Address)); 5023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (host() != NULL) { 5033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* target_code = Code::GetCodeFromTargetAddress(target); 5043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( 5053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch host(), this, HeapObject::cast(target_code)); 5063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 509bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochtemplate <typename ObjectVisitor> 510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) { 511f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke RelocInfo::Mode mode = rmode(); 512f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke if (mode == RelocInfo::EMBEDDED_OBJECT) { 5133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch visitor->VisitEmbeddedPointer(this); 514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Assembler::FlushICache(isolate, pc_, sizeof(Address)); 515f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke } else if (RelocInfo::IsCodeTarget(mode)) { 516f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke visitor->VisitCodeTarget(this); 517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (mode == RelocInfo::CELL) { 518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch visitor->VisitCell(this); 519f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { 5203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch visitor->VisitExternalReference(this); 521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (mode == RelocInfo::INTERNAL_REFERENCE) { 522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch visitor->VisitInternalReference(this); 523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (RelocInfo::IsCodeAgeSequence(mode)) { 524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch visitor->VisitCodeAgeSequence(this); 525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (RelocInfo::IsDebugBreakSlot(mode) && 526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IsPatchedDebugBreakSlotSequence()) { 527f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke visitor->VisitDebugTarget(this); 528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (RelocInfo::IsRuntimeEntry(mode)) { 529f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke visitor->VisitRuntimeEntry(this); 530f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke } 531f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke} 532f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 533f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 534756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merricktemplate<typename StaticVisitor> 53544f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid RelocInfo::Visit(Heap* heap) { 536756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick RelocInfo::Mode mode = rmode(); 537756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick if (mode == RelocInfo::EMBEDDED_OBJECT) { 5383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StaticVisitor::VisitEmbeddedPointer(heap, this); 539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Assembler::FlushICache(heap->isolate(), pc_, sizeof(Address)); 540756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } else if (RelocInfo::IsCodeTarget(mode)) { 5418b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch StaticVisitor::VisitCodeTarget(heap, this); 542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (mode == RelocInfo::CELL) { 543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StaticVisitor::VisitCell(heap, this); 544756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { 5453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StaticVisitor::VisitExternalReference(this); 546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (mode == RelocInfo::INTERNAL_REFERENCE) { 547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch StaticVisitor::VisitInternalReference(this); 548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (RelocInfo::IsCodeAgeSequence(mode)) { 549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StaticVisitor::VisitCodeAgeSequence(heap, this); 550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (RelocInfo::IsDebugBreakSlot(mode) && 551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IsPatchedDebugBreakSlotSequence()) { 5528b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch StaticVisitor::VisitDebugTarget(heap, this); 553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (RelocInfo::IsRuntimeEntry(mode)) { 554756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick StaticVisitor::VisitRuntimeEntry(this); 555756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 556756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick} 557756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 558756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------- 560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Implementation of Operand 561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Operand::set_modrm(int mod, Register rm_reg) { 563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_uint2(mod)); 564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buf_[0] = mod << 6 | rm_reg.low_bits(); 565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set REX.B to the high bit of rm.code(). 566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rex_ |= rm_reg.high_bit(); 567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Operand::set_sib(ScaleFactor scale, Register index, Register base) { 571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(len_ == 1); 572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_uint2(scale)); 573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Use SIB with no index register only for base rsp or r12. Otherwise we 574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // would skip the SIB byte entirely. 575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!index.is(rsp) || base.is(rsp) || base.is(r12)); 5761e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block buf_[1] = (scale << 6) | (index.low_bits() << 3) | base.low_bits(); 577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rex_ |= index.high_bit() << 1 | base.high_bit(); 578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block len_ = 2; 579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Operand::set_disp8(int disp) { 582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_int8(disp)); 583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(len_ == 1 || len_ == 2); 584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int8_t* p = reinterpret_cast<int8_t*>(&buf_[len_]); 585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *p = disp; 586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block len_ += sizeof(int8_t); 587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Operand::set_disp32(int disp) { 590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(len_ == 1 || len_ == 2); 591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int32_t* p = reinterpret_cast<int32_t*>(&buf_[len_]); 592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *p = disp; 593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block len_ += sizeof(int32_t); 594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Operand::set_disp64(int64_t disp) { 597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(1, len_); 598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int64_t* p = reinterpret_cast<int64_t*>(&buf_[len_]); 599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *p = disp; 600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch len_ += sizeof(disp); 601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // V8_X64_ASSEMBLER_X64_INL_H_ 606