1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright (c) 1994-2006 Sun Microsystems Inc. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// All Rights Reserved. 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met: 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - Redistributions of source code must retain the above copyright notice, 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// this list of conditions and the following disclaimer. 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - Redistribution in binary form must reproduce the above copyright 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer in the 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// documentation and/or other materials provided with the distribution. 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - Neither the name of Sun Microsystems or the names of contributors may 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// be used to endorse or promote products derived from this software without 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// specific prior written permission. 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The original source code covered by the above license above has been 32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modified significantly by Google Inc. 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2006-2008 the V8 project authors. All rights reserved. 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A light-weight IA32 Assembler. 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_IA32_ASSEMBLER_IA32_INL_H_ 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_IA32_ASSEMBLER_IA32_INL_H_ 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "cpu.h" 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCondition NegateCondition(Condition cc) { 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<Condition>(cc ^ 1); 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The modes possibly affected by apply must be in kApplyMask. 51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RelocInfo::apply(intptr_t delta) { 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (rmode_ == RUNTIME_ENTRY || IsCodeTarget(rmode_)) { 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int32_t* p = reinterpret_cast<int32_t*>(pc_); 54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *p -= delta; // relocate entry 553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else if (rmode_ == JS_RETURN && IsPatchedReturnSequence()) { 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Special handling of js_return when a break point is set (call 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // instruction has been inserted). 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1); 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *p -= delta; // relocate entry 60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (IsInternalReference(rmode_)) { 61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // absolute code pointer inside code object moves with the code object. 62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int32_t* p = reinterpret_cast<int32_t*>(pc_); 63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *p += delta; // relocate entry 64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress RelocInfo::target_address() { 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY); 70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Assembler::target_address_at(pc_); 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress RelocInfo::target_address_address() { 75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY); 76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return reinterpret_cast<Address>(pc_); 77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RelocInfo::set_target_address(Address target) { 81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY); 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Assembler::set_target_address_at(pc_, target); 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject* RelocInfo::target_object() { 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 883ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return Memory::Object_at(pc_); 893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 903ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 92d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockHandle<Object> RelocInfo::target_object_handle(Assembler* origin) { 933ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 943ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return Memory::Object_Handle_at(pc_); 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject** RelocInfo::target_object_address() { 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 1003ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return &Memory::Object_at(pc_); 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RelocInfo::set_target_object(Object* target) { 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 1063ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Memory::Object_at(pc_) = target; 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress* RelocInfo::target_reference_address() { 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(rmode_ == RelocInfo::EXTERNAL_REFERENCE); 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return reinterpret_cast<Address*>(pc_); 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress RelocInfo::call_address() { 1173ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block ASSERT(IsPatchedReturnSequence()); 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Assembler::target_address_at(pc_ + 1); 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RelocInfo::set_call_address(Address target) { 1233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block ASSERT(IsPatchedReturnSequence()); 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Assembler::set_target_address_at(pc_ + 1, target); 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject* RelocInfo::call_object() { 1293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block ASSERT(IsPatchedReturnSequence()); 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return *call_object_address(); 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject** RelocInfo::call_object_address() { 1353ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block ASSERT(IsPatchedReturnSequence()); 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return reinterpret_cast<Object**>(pc_ + 1); 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RelocInfo::set_call_object(Object* target) { 1413ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block ASSERT(IsPatchedReturnSequence()); 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *call_object_address() = target; 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockbool RelocInfo::IsPatchedReturnSequence() { 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return *pc_ == 0xE8; 148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockImmediate::Immediate(int x) { 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block x_ = x; 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rmode_ = RelocInfo::NONE; 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockImmediate::Immediate(const ExternalReference& ext) { 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block x_ = reinterpret_cast<int32_t>(ext.address()); 159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rmode_ = RelocInfo::EXTERNAL_REFERENCE; 160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockImmediate::Immediate(const char* s) { 163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block x_ = reinterpret_cast<int32_t>(s); 164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rmode_ = RelocInfo::EMBEDDED_STRING; 165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockImmediate::Immediate(Label* internal_offset) { 169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block x_ = reinterpret_cast<int32_t>(internal_offset); 170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rmode_ = RelocInfo::INTERNAL_REFERENCE; 171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockImmediate::Immediate(Handle<Object> handle) { 175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Verify all Objects referred by code are NOT in new space. 176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* obj = *handle; 177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!Heap::InNewSpace(obj)); 178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (obj->IsHeapObject()) { 179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block x_ = reinterpret_cast<intptr_t>(handle.location()); 180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rmode_ = RelocInfo::EMBEDDED_OBJECT; 181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // no relocation needed 183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block x_ = reinterpret_cast<intptr_t>(obj); 184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rmode_ = RelocInfo::NONE; 185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockImmediate::Immediate(Smi* value) { 190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block x_ = reinterpret_cast<intptr_t>(value); 191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rmode_ = RelocInfo::NONE; 192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit(uint32_t x) { 196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *reinterpret_cast<uint32_t*>(pc_) = x; 197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pc_ += sizeof(uint32_t); 198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit(Handle<Object> handle) { 202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Verify all Objects referred by code are NOT in new space. 203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* obj = *handle; 204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!Heap::InNewSpace(obj)); 205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (obj->IsHeapObject()) { 206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(reinterpret_cast<intptr_t>(handle.location()), 207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RelocInfo::EMBEDDED_OBJECT); 208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // no relocation needed 210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(reinterpret_cast<intptr_t>(obj)); 211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit(uint32_t x, RelocInfo::Mode rmode) { 216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (rmode != RelocInfo::NONE) RecordRelocInfo(rmode); 217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(x); 218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit(const Immediate& x) { 222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (x.rmode_ == RelocInfo::INTERNAL_REFERENCE) { 223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label* label = reinterpret_cast<Label*>(x.x_); 224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_code_relative_offset(label); 225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (x.rmode_ != RelocInfo::NONE) RecordRelocInfo(x.rmode_); 228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(x.x_); 229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_code_relative_offset(Label* label) { 233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (label->is_bound()) { 234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int32_t pos; 235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pos = label->pos() + Code::kHeaderSize - kHeapObjectTag; 236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(pos); 237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit_disp(label, Displacement::CODE_RELATIVE); 239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_w(const Immediate& x) { 244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(x.rmode_ == RelocInfo::NONE); 245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint16_t value = static_cast<uint16_t>(x.x_); 246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reinterpret_cast<uint16_t*>(pc_)[0] = value; 247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pc_ += sizeof(uint16_t); 248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress Assembler::target_address_at(Address pc) { 252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return pc + sizeof(int32_t) + *reinterpret_cast<int32_t*>(pc); 253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::set_target_address_at(Address pc, Address target) { 257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int32_t* p = reinterpret_cast<int32_t*>(pc); 258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *p = target - (pc + sizeof(int32_t)); 259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CPU::FlushICache(p, sizeof(int32_t)); 260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockDisplacement Assembler::disp_at(Label* L) { 264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Displacement(long_at(L->pos())); 265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::disp_at_put(Label* L, Displacement disp) { 269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block long_at_put(L->pos(), disp.data()); 270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit_disp(Label* L, Displacement::Type type) { 274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Displacement disp(L, type); 275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block L->link_to(pc_offset()); 276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block emit(static_cast<int>(disp.data())); 277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Operand::set_modrm(int mod, Register rm) { 281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT((mod & -4) == 0); 282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buf_[0] = mod << 6 | rm.code(); 283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block len_ = 1; 284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Operand::set_sib(ScaleFactor scale, Register index, Register base) { 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(len_ == 1); 289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT((scale & -4) == 0); 290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Use SIB with no index register only for base esp. 291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!index.is(esp) || base.is(esp)); 292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buf_[1] = scale << 6 | index.code() << 3 | base.code(); 293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block len_ = 2; 294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Operand::set_disp8(int8_t disp) { 298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(len_ == 1 || len_ == 2); 299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *reinterpret_cast<int8_t*>(&buf_[len_++]) = disp; 300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Operand::set_dispr(int32_t disp, RelocInfo::Mode rmode) { 304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(len_ == 1 || len_ == 2); 305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int32_t* p = reinterpret_cast<int32_t*>(&buf_[len_]); 306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *p = disp; 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block len_ += sizeof(int32_t); 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rmode_ = rmode; 309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockOperand::Operand(Register reg) { 312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // reg 313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_modrm(3, reg); 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockOperand::Operand(int32_t disp, RelocInfo::Mode rmode) { 318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // [disp/r] 319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_modrm(0, ebp); 320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_dispr(disp, rmode); 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // V8_IA32_ASSEMBLER_IA32_INL_H_ 326