assembler-arm-inl.h revision d0582a6c46733687d045e4188a1bcd0123c758a1
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 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// are 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 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// distribution. 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - Neither the name of Sun Microsystems or the names of contributors may 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// be used to endorse or promote products derived from this software without 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// specific prior written permission. 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THE POSSIBILITY OF SUCH DAMAGE. 32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The original source code covered by the above license above has been modified 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// significantly by Google Inc. 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2006-2008 the V8 project authors. All rights reserved. 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_ARM_ASSEMBLER_ARM_INL_H_ 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_ARM_ASSEMBLER_ARM_INL_H_ 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "arm/assembler-arm.h" 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "cpu.h" 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCondition NegateCondition(Condition cc) { 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(cc != al); 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<Condition>(cc ^ ne); 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RelocInfo::apply(intptr_t delta) { 54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (RelocInfo::IsInternalReference(rmode_)) { 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // absolute code pointer inside code object moves with the code object. 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int32_t* p = reinterpret_cast<int32_t*>(pc_); 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *p += delta; // relocate entry 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // We do not use pc relative addressing on ARM, so there is 60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // nothing else to do. 61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress RelocInfo::target_address() { 65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY); 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Assembler::target_address_at(pc_); 67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress RelocInfo::target_address_address() { 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY); 72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return reinterpret_cast<Address>(Assembler::target_address_address_at(pc_)); 73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RelocInfo::set_target_address(Address target) { 77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY); 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Assembler::set_target_address_at(pc_, target); 79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject* RelocInfo::target_object() { 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return Memory::Object_at(Assembler::target_address_address_at(pc_)); 853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 863ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 873ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 88d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockHandle<Object> RelocInfo::target_object_handle(Assembler* origin) { 893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 903ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return Memory::Object_Handle_at(Assembler::target_address_address_at(pc_)); 91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject** RelocInfo::target_object_address() { 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return reinterpret_cast<Object**>(Assembler::target_address_address_at(pc_)); 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RelocInfo::set_target_object(Object* target) { 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Assembler::set_target_address_at(pc_, reinterpret_cast<Address>(target)); 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress* RelocInfo::target_reference_address() { 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(rmode_ == EXTERNAL_REFERENCE); 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return reinterpret_cast<Address*>(Assembler::target_address_address_at(pc_)); 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress RelocInfo::call_address() { 1133ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block ASSERT(IsPatchedReturnSequence()); 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The 2 instructions offset assumes patched return sequence. 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(IsJSReturn(rmode())); 116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Memory::Address_at(pc_ + 2 * Assembler::kInstrSize); 117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RelocInfo::set_call_address(Address target) { 1213ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block ASSERT(IsPatchedReturnSequence()); 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The 2 instructions offset assumes patched return sequence. 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(IsJSReturn(rmode())); 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Memory::Address_at(pc_ + 2 * Assembler::kInstrSize) = target; 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject* RelocInfo::call_object() { 129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return *call_object_address(); 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject** RelocInfo::call_object_address() { 1343ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block ASSERT(IsPatchedReturnSequence()); 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The 2 instructions offset assumes patched return sequence. 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(IsJSReturn(rmode())); 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return reinterpret_cast<Object**>(pc_ + 2 * Assembler::kInstrSize); 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RelocInfo::set_call_object(Object* target) { 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *call_object_address() = target; 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockbool RelocInfo::IsPatchedReturnSequence() { 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // On ARM a "call instruction" is actually two instructions. 148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // mov lr, pc 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ldr pc, [pc, #XXX] 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return (Assembler::instr_at(pc_) == kMovLrPc) 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block && ((Assembler::instr_at(pc_ + Assembler::kInstrSize) & kLdrPCPattern) 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block == kLdrPCPattern); 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockOperand::Operand(int32_t immediate, RelocInfo::Mode rmode) { 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rm_ = no_reg; 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block imm32_ = immediate; 159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rmode_ = rmode; 160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockOperand::Operand(const char* s) { 164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rm_ = no_reg; 165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block imm32_ = reinterpret_cast<int32_t>(s); 166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rmode_ = RelocInfo::EMBEDDED_STRING; 167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockOperand::Operand(const ExternalReference& f) { 171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rm_ = no_reg; 172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block imm32_ = reinterpret_cast<int32_t>(f.address()); 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rmode_ = RelocInfo::EXTERNAL_REFERENCE; 174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockOperand::Operand(Object** opp) { 178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rm_ = no_reg; 179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block imm32_ = reinterpret_cast<int32_t>(opp); 180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rmode_ = RelocInfo::NONE; 181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockOperand::Operand(Context** cpp) { 185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rm_ = no_reg; 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block imm32_ = reinterpret_cast<int32_t>(cpp); 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rmode_ = RelocInfo::NONE; 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockOperand::Operand(Smi* value) { 192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rm_ = no_reg; 193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block imm32_ = reinterpret_cast<intptr_t>(value); 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rmode_ = RelocInfo::NONE; 195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockOperand::Operand(Register rm) { 199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rm_ = rm; 200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rs_ = no_reg; 201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block shift_op_ = LSL; 202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block shift_imm_ = 0; 203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Operand::is_reg() const { 207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return rm_.is_valid() && 208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rs_.is(no_reg) && 209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block shift_op_ == LSL && 210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block shift_imm_ == 0; 211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::CheckBuffer() { 215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (buffer_space() <= kGap) { 216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block GrowBuffer(); 217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (pc_offset() >= next_buffer_check_) { 219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckConstPool(false, true); 220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit(Instr x) { 225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckBuffer(); 226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *reinterpret_cast<Instr*>(pc_) = x; 227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pc_ += kInstrSize; 228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress Assembler::target_address_address_at(Address pc) { 232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Instr instr = Memory::int32_at(pc); 233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Verify that the instruction at pc is a ldr<cond> <Rd>, [pc +/- offset_12]. 234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT((instr & 0x0f7f0000) == 0x051f0000); 235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int offset = instr & 0xfff; // offset_12 is unsigned 236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if ((instr & (1 << 23)) == 0) offset = -offset; // U bit defines offset sign 237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Verify that the constant pool comes after the instruction referencing it. 238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(offset >= -4); 239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return pc + offset + 8; 240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress Assembler::target_address_at(Address pc) { 244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Memory::Address_at(target_address_address_at(pc)); 245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 248d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockvoid Assembler::set_target_at(Address constant_pool_entry, 249d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Address target) { 250d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Memory::Address_at(constant_pool_entry) = target; 251d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 252d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 253d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::set_target_address_at(Address pc, Address target) { 255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Memory::Address_at(target_address_address_at(pc)) = target; 256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Intuitively, we would think it is necessary to flush the instruction cache 257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // after patching a target address in the code as follows: 258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // CPU::FlushICache(pc, sizeof(target)); 259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // However, on ARM, no instruction was actually patched by the assignment 260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // above; the target address is not part of an instruction, it is patched in 261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the constant pool and is read via a data access; the instruction accessing 262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // this address in the constant pool remains unchanged. 263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // V8_ARM_ASSEMBLER_ARM_INL_H_ 268