1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2013 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Redistribution and use in source and binary forms, with or without 4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// modification, are permitted provided that the following conditions are 5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// met: 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// * Redistributions of source code must retain the above copyright 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// notice, this list of conditions and the following disclaimer. 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// * Redistributions in binary form must reproduce the above 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// copyright notice, this list of conditions and the following 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// disclaimer in the documentation and/or other materials provided 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// with the distribution. 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// * Neither the name of Google Inc. nor the names of its 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// contributors may be used to endorse or promote products derived 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// from this software without specific prior written permission. 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if V8_TARGET_ARCH_ARM64 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ARM64_DEFINE_REG_STATICS 32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/arm64/assembler-arm64.h" 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/arm64/assembler-arm64-inl.h" 35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/arm64/frames-arm64.h" 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/bits.h" 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/cpu.h" 38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/register-configuration.h" 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ----------------------------------------------------------------------------- 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// CpuFeatures implementation. 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CpuFeatures::ProbeImpl(bool cross_compile) { 48958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // AArch64 has no configuration options, no further probing is required. 49958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier supported_ = 0; 50958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 51958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Only use statically determined features for cross compile (snapshot). 52958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (cross_compile) return; 53958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 54537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // We used to probe for coherent cache support, but on older CPUs it 55537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // causes crashes (crbug.com/524337), and newer CPUs don't even have 56537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch // the feature any more. 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CpuFeatures::PrintTarget() { } 60537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdochvoid CpuFeatures::PrintFeatures() {} 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ----------------------------------------------------------------------------- 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// CPURegList utilities. 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochCPURegister CPURegList::PopLowestIndex() { 66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsValid()); 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsEmpty()) { 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NoCPUReg; 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int index = CountTrailingZeros(list_, kRegListSizeInBits); 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((1 << index) & list_); 72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Remove(index); 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return CPURegister::Create(index, size_, type_); 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochCPURegister CPURegList::PopHighestIndex() { 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsValid()); 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsEmpty()) { 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NoCPUReg; 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int index = CountLeadingZeros(list_, kRegListSizeInBits); 83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch index = kRegListSizeInBits - 1 - index; 84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((1 << index) & list_); 85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Remove(index); 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return CPURegister::Create(index, size_, type_); 87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CPURegList::RemoveCalleeSaved() { 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (type() == CPURegister::kRegister) { 92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Remove(GetCalleeSaved(RegisterSizeInBits())); 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (type() == CPURegister::kFPRegister) { 94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Remove(GetCalleeSavedFP(RegisterSizeInBits())); 95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(type() == CPURegister::kNoRegister); 97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsEmpty()); 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The list must already be empty, so do nothing. 99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochCPURegList CPURegList::GetCalleeSaved(int size) { 104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return CPURegList(CPURegister::kRegister, size, 19, 29); 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochCPURegList CPURegList::GetCalleeSavedFP(int size) { 109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return CPURegList(CPURegister::kFPRegister, size, 8, 15); 110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochCPURegList CPURegList::GetCallerSaved(int size) { 114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Registers x0-x18 and lr (x30) are caller-saved. 115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CPURegList list = CPURegList(CPURegister::kRegister, size, 0, 18); 116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch list.Combine(lr); 117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return list; 118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochCPURegList CPURegList::GetCallerSavedFP(int size) { 122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Registers d0-d7 and d16-d31 are caller-saved. 123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CPURegList list = CPURegList(CPURegister::kFPRegister, size, 0, 7); 124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch list.Combine(CPURegList(CPURegister::kFPRegister, size, 16, 31)); 125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return list; 126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// This function defines the list of registers which are associated with a 130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// safepoint slot. Safepoint register slots are saved contiguously on the stack. 131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// MacroAssembler::SafepointRegisterStackIndex handles mapping from register 132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// code to index in the safepoint register slots. Any change here can affect 133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// this mapping. 134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochCPURegList CPURegList::GetSafepointSavedRegisters() { 135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CPURegList list = CPURegList::GetCalleeSaved(); 136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch list.Combine( 137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CPURegList(CPURegister::kRegister, kXRegSizeInBits, kJSCallerSaved)); 138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Note that unfortunately we can't use symbolic names for registers and have 140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to directly use register codes. This is because this function is used to 141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // initialize some static variables and we can't rely on register variables 142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to be initialized due to static initialization order issues in C++. 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Drop ip0 and ip1 (i.e. x16 and x17), as they should not be expected to be 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // preserved outside of the macro assembler. 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch list.Remove(16); 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch list.Remove(17); 148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Add x18 to the safepoint list, as although it's not in kJSCallerSaved, it 150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // is a caller-saved register according to the procedure call standard. 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch list.Combine(18); 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Drop jssp as the stack pointer doesn't need to be included. 154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch list.Remove(28); 155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Add the link register (x30) to the safepoint list. 157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch list.Combine(30); 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return list; 160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ----------------------------------------------------------------------------- 164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Implementation of RelocInfo 165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst int RelocInfo::kApplyMask = 1 << RelocInfo::INTERNAL_REFERENCE; 167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool RelocInfo::IsCodedSpecially() { 170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The deserializer needs to know whether a pointer is specially coded. Being 171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // specially coded on ARM64 means that it is a movz/movk sequence. We don't 172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // generate those for relocatable pointers. 173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool RelocInfo::IsInConstantPool() { 178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instruction* instr = reinterpret_cast<Instruction*>(pc_); 179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return instr->IsLdrLiteralX(); 180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 182537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben MurdochAddress RelocInfo::wasm_memory_reference() { 183537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch DCHECK(IsWasmMemoryReference(rmode_)); 184537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch return Memory::Address_at(Assembler::target_pointer_address_at(pc_)); 185537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 186537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 187537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdochuint32_t RelocInfo::wasm_memory_size_reference() { 188537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch DCHECK(IsWasmMemorySizeReference(rmode_)); 189537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch return Memory::uint32_at(Assembler::target_pointer_address_at(pc_)); 190537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 191537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch 19221efce637eb329c94f1323b6a2334a1c977e1a9dBen MurdochAddress RelocInfo::wasm_global_reference() { 19321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch DCHECK(IsWasmGlobalReference(rmode_)); 19421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return Memory::Address_at(Assembler::target_pointer_address_at(pc_)); 19521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 19621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 19721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochvoid RelocInfo::unchecked_update_wasm_memory_reference( 19821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Address address, ICacheFlushMode flush_mode) { 19921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Assembler::set_target_address_at(isolate_, pc_, host_, address, flush_mode); 20021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 20121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 20221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochvoid RelocInfo::unchecked_update_wasm_memory_size(uint32_t size, 20321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch ICacheFlushMode flush_mode) { 20421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Memory::uint32_at(Assembler::target_pointer_address_at(pc_)) = size; 205537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch} 206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochRegister GetAllocatableRegisterThatIsNotOneOf(Register reg1, Register reg2, 208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg3, Register reg4) { 209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CPURegList regs(reg1, reg2, reg3, reg4); 21021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch const RegisterConfiguration* config = RegisterConfiguration::Crankshaft(); 211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < config->num_allocatable_double_registers(); ++i) { 212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int code = config->GetAllocatableDoubleCode(i); 213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register candidate = Register::from_code(code); 214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (regs.IncludesAliasOf(candidate)) continue; 215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return candidate; 216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NoReg; 219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool AreAliased(const CPURegister& reg1, const CPURegister& reg2, 223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const CPURegister& reg3, const CPURegister& reg4, 224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const CPURegister& reg5, const CPURegister& reg6, 225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const CPURegister& reg7, const CPURegister& reg8) { 226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int number_of_valid_regs = 0; 227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int number_of_valid_fpregs = 0; 228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RegList unique_regs = 0; 230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RegList unique_fpregs = 0; 231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const CPURegister regs[] = {reg1, reg2, reg3, reg4, reg5, reg6, reg7, reg8}; 233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (unsigned i = 0; i < arraysize(regs); i++) { 235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (regs[i].IsRegister()) { 236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch number_of_valid_regs++; 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unique_regs |= regs[i].Bit(); 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (regs[i].IsFPRegister()) { 239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch number_of_valid_fpregs++; 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unique_fpregs |= regs[i].Bit(); 241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!regs[i].IsValid()); 243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int number_of_unique_regs = 247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CountSetBits(unique_regs, sizeof(unique_regs) * kBitsPerByte); 248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int number_of_unique_fpregs = 249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CountSetBits(unique_fpregs, sizeof(unique_fpregs) * kBitsPerByte); 250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(number_of_valid_regs >= number_of_unique_regs); 252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(number_of_valid_fpregs >= number_of_unique_fpregs); 253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return (number_of_valid_regs != number_of_unique_regs) || 255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (number_of_valid_fpregs != number_of_unique_fpregs); 256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool AreSameSizeAndType(const CPURegister& reg1, const CPURegister& reg2, 260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const CPURegister& reg3, const CPURegister& reg4, 261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const CPURegister& reg5, const CPURegister& reg6, 262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const CPURegister& reg7, const CPURegister& reg8) { 263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(reg1.IsValid()); 264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool match = true; 265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch match &= !reg2.IsValid() || reg2.IsSameSizeAndType(reg1); 266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch match &= !reg3.IsValid() || reg3.IsSameSizeAndType(reg1); 267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch match &= !reg4.IsValid() || reg4.IsSameSizeAndType(reg1); 268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch match &= !reg5.IsValid() || reg5.IsSameSizeAndType(reg1); 269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch match &= !reg6.IsValid() || reg6.IsSameSizeAndType(reg1); 270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch match &= !reg7.IsValid() || reg7.IsSameSizeAndType(reg1); 271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch match &= !reg8.IsValid() || reg8.IsSameSizeAndType(reg1); 272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return match; 273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Immediate::InitializeHandle(Handle<Object> handle) { 277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllowDeferredHandleDereference using_raw_address; 278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Verify all Objects referred by code are NOT in new space. 280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* obj = *handle; 281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (obj->IsHeapObject()) { 282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HeapObject::cast(obj)->GetHeap()->InNewSpace(obj)); 283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value_ = reinterpret_cast<intptr_t>(handle.location()); 284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch rmode_ = RelocInfo::EMBEDDED_OBJECT; 285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(sizeof(intptr_t) == sizeof(int64_t)); 287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value_ = reinterpret_cast<intptr_t>(obj); 288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch rmode_ = RelocInfo::NONE64; 289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Operand::NeedsRelocation(const Assembler* assembler) const { 294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RelocInfo::Mode rmode = immediate_.rmode(); 295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (rmode == RelocInfo::EXTERNAL_REFERENCE) { 297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return assembler->serializer_enabled(); 298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return !RelocInfo::IsNone(rmode); 301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Constant Pool. 305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid ConstPool::RecordEntry(intptr_t data, 306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RelocInfo::Mode mode) { 307537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch DCHECK(mode != RelocInfo::COMMENT && mode != RelocInfo::POSITION && 308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mode != RelocInfo::STATEMENT_POSITION && 309537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch mode != RelocInfo::CONST_POOL && mode != RelocInfo::VENEER_POOL && 310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch mode != RelocInfo::CODE_AGE_SEQUENCE && 311537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch mode != RelocInfo::DEOPT_REASON && mode != RelocInfo::DEOPT_ID); 312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint64_t raw_data = static_cast<uint64_t>(data); 313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int offset = assm_->pc_offset(); 314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsEmpty()) { 315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch first_use_ = offset; 316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch std::pair<uint64_t, int> entry = std::make_pair(raw_data, offset); 319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (CanBeShared(mode)) { 320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shared_entries_.insert(entry); 321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (shared_entries_.count(entry.first) == 1) { 322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shared_entries_count++; 323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unique_entries_.push_back(entry); 326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (EntryCount() > Assembler::kApproxMaxPoolEntryCount) { 329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Request constant pool emission after the next instruction. 330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assm_->SetNextConstPoolCheckIn(1); 331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint ConstPool::DistanceToFirstUse() { 336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(first_use_ >= 0); 337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return assm_->pc_offset() - first_use_; 338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint ConstPool::MaxPcOffset() { 342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // There are no pending entries in the pool so we can never get out of 343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // range. 344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsEmpty()) return kMaxInt; 345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Entries are not necessarily emitted in the order they are added so in the 347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // worst case the first constant pool use will be accessing the last entry. 348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return first_use_ + kMaxLoadLiteralRange - WorstCaseSize(); 349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint ConstPool::WorstCaseSize() { 353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsEmpty()) return 0; 354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Max size prologue: 356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // b over 357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // ldr xzr, #pool_size 358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // blr xzr 359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // nop 360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // All entries are 64-bit for now. 361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return 4 * kInstructionSize + EntryCount() * kPointerSize; 362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint ConstPool::SizeIfEmittedAtCurrentPc(bool require_jump) { 366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsEmpty()) return 0; 367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Prologue is: 369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // b over ;; if require_jump 370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // ldr xzr, #pool_size 371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // blr xzr 372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // nop ;; if not 64-bit aligned 373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int prologue_size = require_jump ? kInstructionSize : 0; 374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch prologue_size += 2 * kInstructionSize; 375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch prologue_size += IsAligned(assm_->pc_offset() + prologue_size, 8) ? 376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 0 : kInstructionSize; 377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // All entries are 64-bit for now. 379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return prologue_size + EntryCount() * kPointerSize; 380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid ConstPool::Emit(bool require_jump) { 384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!assm_->is_const_pool_blocked()); 385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Prevent recursive pool emission and protect from veneer pools. 386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler::BlockPoolsScope block_pools(assm_); 387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int size = SizeIfEmittedAtCurrentPc(require_jump); 389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label size_check; 390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assm_->bind(&size_check); 391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assm_->RecordConstPool(size); 393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Emit the constant pool. It is preceded by an optional branch if 394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // require_jump and a header which will: 395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 1) Encode the size of the constant pool, for use by the disassembler. 396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 2) Terminate the program, to try to prevent execution from accidentally 397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // flowing into the constant pool. 398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 3) align the pool entries to 64-bit. 399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The header is therefore made of up to three arm64 instructions: 400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // ldr xzr, #<size of the constant pool in 32-bit words> 401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // blr xzr 402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // nop 403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If executed, the header will likely segfault and lr will point to the 405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // instruction following the offending blr. 406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(all): Make the alignment part less fragile. Currently code is 407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // allocated as a byte array so there are no guarantees the alignment will 408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // be preserved on compaction. Currently it works as allocation seems to be 409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 64-bit aligned. 410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Emit branch if required 412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label after_pool; 413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (require_jump) { 414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assm_->b(&after_pool); 415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Emit the header. 418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assm_->RecordComment("[ Constant Pool"); 419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EmitMarker(); 420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EmitGuard(); 421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assm_->Align(8); 422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Emit constant pool entries. 424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(all): currently each relocated constant is 64 bits, consider adding 425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // support for 32-bit entries. 426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EmitEntries(); 427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assm_->RecordComment("]"); 428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (after_pool.is_linked()) { 430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assm_->bind(&after_pool); 431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(assm_->SizeOfCodeGeneratedSince(&size_check) == 434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<unsigned>(size)); 435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid ConstPool::Clear() { 439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shared_entries_.clear(); 440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shared_entries_count = 0; 441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unique_entries_.clear(); 442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch first_use_ = -1; 443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool ConstPool::CanBeShared(RelocInfo::Mode mode) { 447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Constant pool currently does not support 32-bit entries. 448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(mode != RelocInfo::NONE32); 449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return RelocInfo::IsNone(mode) || 4511b268ca467c924004286c97bac133db489cf43d0Ben Murdoch (!assm_->serializer_enabled() && 4521b268ca467c924004286c97bac133db489cf43d0Ben Murdoch (mode >= RelocInfo::FIRST_SHAREABLE_RELOC_MODE)); 453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid ConstPool::EmitMarker() { 457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // A constant pool size is expressed in number of 32-bits words. 458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Currently all entries are 64-bit. 459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // + 1 is for the crash guard. 460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // + 0/1 for alignment. 461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int word_count = EntryCount() * 2 + 1 + 462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (IsAligned(assm_->pc_offset(), 8) ? 0 : 1); 463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assm_->Emit(LDR_x_lit | 464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler::ImmLLiteral(word_count) | 465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler::Rt(xzr)); 466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochMemOperand::PairResult MemOperand::AreConsistentForPair( 470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const MemOperand& operandA, 471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const MemOperand& operandB, 472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int access_size_log2) { 473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(access_size_log2 >= 0); 474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(access_size_log2 <= 3); 475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Step one: check that they share the same base, that the mode is Offset 476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // and that the offset is a multiple of access size. 477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!operandA.base().Is(operandB.base()) || 478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (operandA.addrmode() != Offset) || 479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (operandB.addrmode() != Offset) || 480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ((operandA.offset() & ((1 << access_size_log2) - 1)) != 0)) { 481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return kNotPair; 482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Step two: check that the offsets are contiguous and that the range 484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // is OK for ldp/stp. 485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((operandB.offset() == operandA.offset() + (1 << access_size_log2)) && 486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch is_int7(operandA.offset() >> access_size_log2)) { 487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return kPairAB; 488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((operandA.offset() == operandB.offset() + (1 << access_size_log2)) && 490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch is_int7(operandB.offset() >> access_size_log2)) { 491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return kPairBA; 492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return kNotPair; 494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid ConstPool::EmitGuard() { 498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instruction* instr = reinterpret_cast<Instruction*>(assm_->pc()); 500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(instr->preceding()->IsLdrLiteralX() && 501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr->preceding()->Rt() == xzr.code()); 502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assm_->EmitPoolGuard(); 504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid ConstPool::EmitEntries() { 508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsAligned(assm_->pc_offset(), 8)); 509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typedef std::multimap<uint64_t, int>::const_iterator SharedEntriesIterator; 511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SharedEntriesIterator value_it; 512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Iterate through the keys (constant pool values). 513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (value_it = shared_entries_.begin(); 514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value_it != shared_entries_.end(); 515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value_it = shared_entries_.upper_bound(value_it->first)) { 516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch std::pair<SharedEntriesIterator, SharedEntriesIterator> range; 517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint64_t data = value_it->first; 518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch range = shared_entries_.equal_range(data); 519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SharedEntriesIterator offset_it; 520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Iterate through the offsets of a given key. 521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (offset_it = range.first; offset_it != range.second; offset_it++) { 522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instruction* instr = assm_->InstructionAt(offset_it->second); 523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Instruction to patch must be 'ldr rd, [pc, #offset]' with offset == 0. 525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(instr->IsLdrLiteral() && instr->ImmLLiteral() == 0); 526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch instr->SetImmPCOffsetTarget(assm_->isolate(), assm_->pc()); 527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assm_->dc64(data); 529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shared_entries_.clear(); 531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shared_entries_count = 0; 532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Emit unique entries. 534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch std::vector<std::pair<uint64_t, int> >::const_iterator unique_it; 535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (unique_it = unique_entries_.begin(); 536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unique_it != unique_entries_.end(); 537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unique_it++) { 538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instruction* instr = assm_->InstructionAt(unique_it->second); 539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Instruction to patch must be 'ldr rd, [pc, #offset]' with offset == 0. 541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(instr->IsLdrLiteral() && instr->ImmLLiteral() == 0); 542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch instr->SetImmPCOffsetTarget(assm_->isolate(), assm_->pc()); 543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assm_->dc64(unique_it->first); 544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unique_entries_.clear(); 546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch first_use_ = -1; 547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Assembler 551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAssembler::Assembler(Isolate* isolate, void* buffer, int buffer_size) 552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : AssemblerBase(isolate, buffer, buffer_size), 553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constpool_(this), 554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch recorded_ast_id_(TypeFeedbackId::None()), 555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unresolved_branches_(), 556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch positions_recorder_(this) { 557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const_pool_blocked_nesting_ = 0; 558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch veneer_pool_blocked_nesting_ = 0; 559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Reset(); 560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAssembler::~Assembler() { 564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(constpool_.IsEmpty()); 565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(const_pool_blocked_nesting_ == 0); 566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(veneer_pool_blocked_nesting_ == 0); 567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::Reset() { 571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((pc_ >= buffer_) && (pc_ < buffer_ + buffer_size_)); 573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(const_pool_blocked_nesting_ == 0); 574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(veneer_pool_blocked_nesting_ == 0); 575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(unresolved_branches_.empty()); 576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch memset(buffer_, 0, pc_ - buffer_); 577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pc_ = buffer_; 579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reloc_info_writer.Reposition(reinterpret_cast<byte*>(buffer_ + buffer_size_), 580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<byte*>(pc_)); 581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constpool_.Clear(); 582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch next_constant_pool_check_ = 0; 583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch next_veneer_pool_check_ = kMaxInt; 584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch no_const_pool_before_ = 0; 585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClearRecordedAstId(); 586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::GetCode(CodeDesc* desc) { 590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch reloc_info_writer.Finish(); 591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Emit constant pool if necessary. 592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CheckConstPool(true, false); 593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(constpool_.IsEmpty()); 594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set up code descriptor. 596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (desc) { 597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc->buffer = reinterpret_cast<byte*>(buffer_); 598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc->buffer_size = buffer_size_; 599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc->instr_size = pc_offset(); 600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch desc->reloc_size = 601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static_cast<int>((reinterpret_cast<byte*>(buffer_) + buffer_size_) - 602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch reloc_info_writer.pos()); 603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc->origin = this; 604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch desc->constant_pool_size = 0; 60521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch desc->unwinding_info_size = 0; 60621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch desc->unwinding_info = nullptr; 607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::Align(int m) { 612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(m >= 4 && base::bits::IsPowerOfTwo32(m)); 613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while ((pc_offset() & (m - 1)) != 0) { 614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch nop(); 615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::CheckLabelLinkChain(Label const * label) { 620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (label->is_linked()) { 622958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static const int kMaxLinksToCheck = 64; // Avoid O(n2) behaviour. 623958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int links_checked = 0; 624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int64_t linkoffset = label->pos(); 625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool end_of_chain = false; 626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (!end_of_chain) { 627958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (++links_checked > kMaxLinksToCheck) break; 628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instruction * link = InstructionAt(linkoffset); 629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int64_t linkpcoffset = link->ImmPCOffset(); 630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int64_t prevlinkoffset = linkoffset + linkpcoffset; 631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch end_of_chain = (linkoffset == prevlinkoffset); 633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch linkoffset = linkoffset + linkpcoffset; 634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::RemoveBranchFromLabelLinkChain(Instruction* branch, 641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* label, 642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instruction* label_veneer) { 643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(label->is_linked()); 644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CheckLabelLinkChain(label); 646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instruction* link = InstructionAt(label->pos()); 648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instruction* prev_link = link; 649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instruction* next_link; 650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool end_of_chain = false; 651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (link != branch && !end_of_chain) { 653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch next_link = link->ImmPCOffsetTarget(); 654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch end_of_chain = (link == next_link); 655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch prev_link = link; 656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch link = next_link; 657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(branch == link); 660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch next_link = branch->ImmPCOffsetTarget(); 661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (branch == prev_link) { 663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The branch is the first instruction in the chain. 664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (branch == next_link) { 665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // It is also the last instruction in the chain, so it is the only branch 666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // currently referring to this label. 667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch label->Unuse(); 668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch label->link_to( 670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static_cast<int>(reinterpret_cast<byte*>(next_link) - buffer_)); 671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (branch == next_link) { 674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The branch is the last (but not also the first) instruction in the chain. 675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch prev_link->SetImmPCOffsetTarget(isolate(), prev_link); 676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The branch is in the middle of the chain. 679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (prev_link->IsTargetInImmPCOffsetRange(next_link)) { 680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch prev_link->SetImmPCOffsetTarget(isolate(), next_link); 681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (label_veneer != NULL) { 682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Use the veneer for all previous links in the chain. 683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch prev_link->SetImmPCOffsetTarget(isolate(), prev_link); 684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch end_of_chain = false; 686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch link = next_link; 687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (!end_of_chain) { 688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch next_link = link->ImmPCOffsetTarget(); 689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch end_of_chain = (link == next_link); 690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch link->SetImmPCOffsetTarget(isolate(), label_veneer); 691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch link = next_link; 692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The assert below will fire. 695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Some other work could be attempted to fix up the chain, but it would be 696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // rather complicated. If we crash here, we may want to consider using an 697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // other mechanism than a chain of branches. 698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Note that this situation currently should not happen, as we always call 700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // this function with a veneer to the target label. 701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // However this could happen with a MacroAssembler in the following state: 702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // [previous code] 703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // B(label); 704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // [20KB code] 705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Tbz(label); // First tbz. Pointing to unconditional branch. 706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // [20KB code] 707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Tbz(label); // Second tbz. Pointing to the first tbz. 708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // [more code] 709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // and this function is called to remove the first tbz from the label link 710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // chain. Since tbz has a range of +-32KB, the second tbz cannot point to 711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the unconditional branch. 712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(prev_link->IsTargetInImmPCOffsetRange(next_link)); 713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CheckLabelLinkChain(label); 718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bind(Label* label) { 722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Bind label to the address at pc_. All instructions (most likely branches) 723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // that are linked to this label will be updated to point to the newly-bound 724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // label. 725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!label->is_near_linked()); 727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!label->is_bound()); 728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DeleteUnresolvedBranchInfoForLabel(label); 730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the label is linked, the link chain looks something like this: 732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // |--I----I-------I-------L 734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // |---------------------->| pc_offset 735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // |-------------->| linkoffset = label->pos() 736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // |<------| link->ImmPCOffset() 737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // |------>| prevlinkoffset = linkoffset + link->ImmPCOffset() 738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // On each iteration, the last link is updated and then removed from the 740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // chain until only one remains. At that point, the label is bound. 741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the label is not linked, no preparation is required before binding. 743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (label->is_linked()) { 744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int linkoffset = label->pos(); 745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instruction* link = InstructionAt(linkoffset); 746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int prevlinkoffset = linkoffset + static_cast<int>(link->ImmPCOffset()); 747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CheckLabelLinkChain(label); 749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(linkoffset >= 0); 751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(linkoffset < pc_offset()); 752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((linkoffset > prevlinkoffset) || 753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (linkoffset - prevlinkoffset == kStartOfLabelLinkChain)); 754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(prevlinkoffset >= 0); 755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Update the link to point to the label. 757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (link->IsUnresolvedInternalReference()) { 758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Internal references do not get patched to an instruction but directly 759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // to an address. 760014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch internal_reference_positions_.push_back(linkoffset); 761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PatchingAssembler patcher(isolate(), link, 2); 762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch patcher.dc64(reinterpret_cast<uintptr_t>(pc_)); 763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch link->SetImmPCOffsetTarget(isolate(), 765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch reinterpret_cast<Instruction*>(pc_)); 766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Link the label to the previous link in the chain. 769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (linkoffset - prevlinkoffset == kStartOfLabelLinkChain) { 770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We hit kStartOfLabelLinkChain, so the chain is fully processed. 771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch label->Unuse(); 772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Update the label for the next iteration. 774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch label->link_to(prevlinkoffset); 775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch label->bind_to(pc_offset()); 778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(label->is_bound()); 780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!label->is_linked()); 781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint Assembler::LinkAndGetByteOffsetTo(Label* label) { 785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(sizeof(*pc_) == 1); 786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CheckLabelLinkChain(label); 787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int offset; 789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (label->is_bound()) { 790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The label is bound, so it does not need to be updated. Referring 791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // instructions must link directly to the label as they will not be 792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // updated. 793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // In this case, label->pos() returns the offset of the label from the 795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // start of the buffer. 796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Note that offset can be zero for self-referential instructions. (This 798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // could be useful for ADR, for example.) 799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch offset = label->pos() - pc_offset(); 800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(offset <= 0); 801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (label->is_linked()) { 803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The label is linked, so the referring instruction should be added onto 804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the end of the label's link chain. 805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // In this case, label->pos() returns the offset of the last linked 807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // instruction from the start of the buffer. 808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch offset = label->pos() - pc_offset(); 809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(offset != kStartOfLabelLinkChain); 810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Note that the offset here needs to be PC-relative only so that the 811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // first instruction in a buffer can link to an unbound label. Otherwise, 812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the offset would be 0 for this case, and 0 is reserved for 813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // kStartOfLabelLinkChain. 814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The label is unused, so it now becomes linked and the referring 816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // instruction is at the start of the new link chain. 817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch offset = kStartOfLabelLinkChain; 818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The instruction at pc is now the last link in the label's chain. 820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch label->link_to(pc_offset()); 821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return offset; 824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::DeleteUnresolvedBranchInfoForLabelTraverse(Label* label) { 828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(label->is_linked()); 829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CheckLabelLinkChain(label); 830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int link_offset = label->pos(); 832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int link_pcoffset; 833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool end_of_chain = false; 834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (!end_of_chain) { 836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instruction * link = InstructionAt(link_offset); 837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch link_pcoffset = static_cast<int>(link->ImmPCOffset()); 838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // ADR instructions are not handled by veneers. 840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (link->IsImmBranch()) { 841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int max_reachable_pc = 842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static_cast<int>(InstructionOffset(link) + 843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Instruction::ImmBranchRange(link->BranchType())); 844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typedef std::multimap<int, FarBranchInfo>::iterator unresolved_info_it; 845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch std::pair<unresolved_info_it, unresolved_info_it> range; 846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch range = unresolved_branches_.equal_range(max_reachable_pc); 847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unresolved_info_it it; 848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (it = range.first; it != range.second; ++it) { 849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (it->second.pc_offset_ == link_offset) { 850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unresolved_branches_.erase(it); 851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch end_of_chain = (link_pcoffset == 0); 857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch link_offset = link_offset + link_pcoffset; 858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::DeleteUnresolvedBranchInfoForLabel(Label* label) { 863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (unresolved_branches_.empty()) { 864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(next_veneer_pool_check_ == kMaxInt); 865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (label->is_linked()) { 869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Branches to this label will be resolved when the label is bound, normally 870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // just after all the associated info has been deleted. 871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DeleteUnresolvedBranchInfoForLabelTraverse(label); 872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (unresolved_branches_.empty()) { 874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch next_veneer_pool_check_ = kMaxInt; 875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch next_veneer_pool_check_ = 877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unresolved_branches_first_limit() - kVeneerDistanceCheckMargin; 878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::StartBlockConstPool() { 883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (const_pool_blocked_nesting_++ == 0) { 884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Prevent constant pool checks happening by setting the next check to 885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the biggest possible offset. 886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch next_constant_pool_check_ = kMaxInt; 887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::EndBlockConstPool() { 892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (--const_pool_blocked_nesting_ == 0) { 893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check the constant pool hasn't been blocked for too long. 894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(pc_offset() < constpool_.MaxPcOffset()); 895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Two cases: 896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // * no_const_pool_before_ >= next_constant_pool_check_ and the emission is 897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // still blocked 898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // * no_const_pool_before_ < next_constant_pool_check_ and the next emit 899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // will trigger a check. 900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch next_constant_pool_check_ = no_const_pool_before_; 901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::is_const_pool_blocked() const { 906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return (const_pool_blocked_nesting_ > 0) || 907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (pc_offset() < no_const_pool_before_); 908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsConstantPoolAt(Instruction* instr) { 912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The constant pool marker is made of two instructions. These instructions 913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // will never be emitted by the JIT, so checking for the first one is enough: 914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 0: ldr xzr, #<size of pool> 915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool result = instr->IsLdrLiteralX() && (instr->Rt() == kZeroRegCode); 916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // It is still worth asserting the marker is complete. 918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 4: blr xzr 919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!result || (instr->following()->IsBranchAndLinkToRegister() && 920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch instr->following()->Rn() == kZeroRegCode)); 921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint Assembler::ConstantPoolSizeAt(Instruction* instr) { 927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef USE_SIMULATOR 928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Assembler::debug() embeds constants directly into the instruction stream. 929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Although this is not a genuine constant pool, treat it like one to avoid 930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // disassembling the constants. 931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((instr->Mask(ExceptionMask) == HLT) && 932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (instr->ImmException() == kImmExceptionIsDebug)) { 933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* message = 934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<const char*>( 935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr->InstructionAtOffset(kDebugMessageOffset)); 936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int size = static_cast<int>(kDebugMessageOffset + strlen(message) + 1); 937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return RoundUp(size, kInstructionSize) / kInstructionSize; 938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Same for printf support, see MacroAssembler::CallPrintf(). 940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((instr->Mask(ExceptionMask) == HLT) && 941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (instr->ImmException() == kImmExceptionIsPrintf)) { 942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return kPrintfLength / kInstructionSize; 943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsConstantPoolAt(instr)) { 946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return instr->ImmLLiteral(); 947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return -1; 949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::EmitPoolGuard() { 954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We must generate only one instruction as this is used in scopes that 955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // control the size of the code generated. 956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(BLR | Rn(xzr)); 957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::StartBlockVeneerPool() { 961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ++veneer_pool_blocked_nesting_; 962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::EndBlockVeneerPool() { 966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (--veneer_pool_blocked_nesting_ == 0) { 967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check the veneer pool hasn't been blocked for too long. 968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(unresolved_branches_.empty() || 969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (pc_offset() < unresolved_branches_first_limit())); 970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::br(const Register& xn) { 975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(xn.Is64Bits()); 976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(BR | Rn(xn)); 977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::blr(const Register& xn) { 981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(xn.Is64Bits()); 982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The pattern 'blr xzr' is used as a guard to detect when execution falls 983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // through the constant pool. It should not be emitted. 984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!xn.Is(xzr)); 985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(BLR | Rn(xn)); 986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ret(const Register& xn) { 990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(xn.Is64Bits()); 991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(RET | Rn(xn)); 992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::b(int imm26) { 996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(B | ImmUncondBranch(imm26)); 997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::b(Label* label) { 1001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch b(LinkAndGetInstructionOffsetTo(label)); 1002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::b(int imm19, Condition cond) { 1006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(B_cond | ImmCondBranch(imm19) | cond); 1007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::b(Label* label, Condition cond) { 1011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch b(LinkAndGetInstructionOffsetTo(label), cond); 1012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bl(int imm26) { 1016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(BL | ImmUncondBranch(imm26)); 1017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bl(Label* label) { 1021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bl(LinkAndGetInstructionOffsetTo(label)); 1022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::cbz(const Register& rt, 1026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int imm19) { 1027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(SF(rt) | CBZ | ImmCmpBranch(imm19) | Rt(rt)); 1028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::cbz(const Register& rt, 1032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* label) { 1033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cbz(rt, LinkAndGetInstructionOffsetTo(label)); 1034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::cbnz(const Register& rt, 1038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int imm19) { 1039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(SF(rt) | CBNZ | ImmCmpBranch(imm19) | Rt(rt)); 1040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::cbnz(const Register& rt, 1044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* label) { 1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cbnz(rt, LinkAndGetInstructionOffsetTo(label)); 1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::tbz(const Register& rt, 1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned bit_pos, 1051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int imm14) { 1052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rt.Is64Bits() || (rt.Is32Bits() && (bit_pos < kWRegSizeInBits))); 1053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(TBZ | ImmTestBranchBit(bit_pos) | ImmTestBranch(imm14) | Rt(rt)); 1054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::tbz(const Register& rt, 1058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned bit_pos, 1059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* label) { 1060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch tbz(rt, bit_pos, LinkAndGetInstructionOffsetTo(label)); 1061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::tbnz(const Register& rt, 1065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned bit_pos, 1066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int imm14) { 1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rt.Is64Bits() || (rt.Is32Bits() && (bit_pos < kWRegSizeInBits))); 1068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(TBNZ | ImmTestBranchBit(bit_pos) | ImmTestBranch(imm14) | Rt(rt)); 1069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::tbnz(const Register& rt, 1073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned bit_pos, 1074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* label) { 1075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch tbnz(rt, bit_pos, LinkAndGetInstructionOffsetTo(label)); 1076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::adr(const Register& rd, int imm21) { 1080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rd.Is64Bits()); 1081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(ADR | ImmPCRelAddress(imm21) | Rd(rd)); 1082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::adr(const Register& rd, Label* label) { 1086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch adr(rd, LinkAndGetByteOffsetTo(label)); 1087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::add(const Register& rd, 1091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 1092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operand& operand) { 1093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddSub(rd, rn, operand, LeaveFlags, ADD); 1094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::adds(const Register& rd, 1098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 1099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operand& operand) { 1100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddSub(rd, rn, operand, SetFlags, ADD); 1101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::cmn(const Register& rn, 1105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operand& operand) { 1106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register zr = AppropriateZeroRegFor(rn); 1107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch adds(zr, rn, operand); 1108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::sub(const Register& rd, 1112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 1113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operand& operand) { 1114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddSub(rd, rn, operand, LeaveFlags, SUB); 1115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::subs(const Register& rd, 1119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 1120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operand& operand) { 1121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddSub(rd, rn, operand, SetFlags, SUB); 1122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::cmp(const Register& rn, const Operand& operand) { 1126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register zr = AppropriateZeroRegFor(rn); 1127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subs(zr, rn, operand); 1128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::neg(const Register& rd, const Operand& operand) { 1132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register zr = AppropriateZeroRegFor(rd); 1133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sub(rd, zr, operand); 1134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::negs(const Register& rd, const Operand& operand) { 1138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register zr = AppropriateZeroRegFor(rd); 1139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subs(rd, zr, operand); 1140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::adc(const Register& rd, 1144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 1145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operand& operand) { 1146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddSubWithCarry(rd, rn, operand, LeaveFlags, ADC); 1147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::adcs(const Register& rd, 1151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 1152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operand& operand) { 1153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddSubWithCarry(rd, rn, operand, SetFlags, ADC); 1154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::sbc(const Register& rd, 1158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 1159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operand& operand) { 1160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddSubWithCarry(rd, rn, operand, LeaveFlags, SBC); 1161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::sbcs(const Register& rd, 1165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 1166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operand& operand) { 1167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddSubWithCarry(rd, rn, operand, SetFlags, SBC); 1168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ngc(const Register& rd, const Operand& operand) { 1172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register zr = AppropriateZeroRegFor(rd); 1173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sbc(rd, zr, operand); 1174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ngcs(const Register& rd, const Operand& operand) { 1178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register zr = AppropriateZeroRegFor(rd); 1179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sbcs(rd, zr, operand); 1180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Logical instructions. 1184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::and_(const Register& rd, 1185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 1186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operand& operand) { 1187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Logical(rd, rn, operand, AND); 1188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ands(const Register& rd, 1192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 1193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operand& operand) { 1194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Logical(rd, rn, operand, ANDS); 1195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::tst(const Register& rn, 1199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operand& operand) { 1200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ands(AppropriateZeroRegFor(rn), rn, operand); 1201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bic(const Register& rd, 1205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 1206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operand& operand) { 1207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Logical(rd, rn, operand, BIC); 1208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::bics(const Register& rd, 1212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 1213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operand& operand) { 1214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Logical(rd, rn, operand, BICS); 1215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::orr(const Register& rd, 1219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 1220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operand& operand) { 1221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Logical(rd, rn, operand, ORR); 1222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::orn(const Register& rd, 1226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 1227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operand& operand) { 1228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Logical(rd, rn, operand, ORN); 1229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::eor(const Register& rd, 1233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 1234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operand& operand) { 1235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Logical(rd, rn, operand, EOR); 1236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::eon(const Register& rd, 1240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 1241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operand& operand) { 1242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Logical(rd, rn, operand, EON); 1243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::lslv(const Register& rd, 1247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 1248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rm) { 1249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rd.SizeInBits() == rn.SizeInBits()); 1250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rd.SizeInBits() == rm.SizeInBits()); 1251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(SF(rd) | LSLV | Rm(rm) | Rn(rn) | Rd(rd)); 1252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::lsrv(const Register& rd, 1256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 1257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rm) { 1258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rd.SizeInBits() == rn.SizeInBits()); 1259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rd.SizeInBits() == rm.SizeInBits()); 1260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(SF(rd) | LSRV | Rm(rm) | Rn(rn) | Rd(rd)); 1261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::asrv(const Register& rd, 1265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 1266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rm) { 1267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rd.SizeInBits() == rn.SizeInBits()); 1268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rd.SizeInBits() == rm.SizeInBits()); 1269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(SF(rd) | ASRV | Rm(rm) | Rn(rn) | Rd(rd)); 1270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::rorv(const Register& rd, 1274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 1275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rm) { 1276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rd.SizeInBits() == rn.SizeInBits()); 1277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rd.SizeInBits() == rm.SizeInBits()); 1278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(SF(rd) | RORV | Rm(rm) | Rn(rn) | Rd(rd)); 1279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Bitfield operations. 1283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::bfm(const Register& rd, const Register& rn, int immr, 1284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int imms) { 1285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rd.SizeInBits() == rn.SizeInBits()); 1286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instr N = SF(rd) >> (kSFOffset - kBitfieldNOffset); 1287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(SF(rd) | BFM | N | 1288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ImmR(immr, rd.SizeInBits()) | 1289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ImmS(imms, rn.SizeInBits()) | 1290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Rn(rn) | Rd(rd)); 1291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::sbfm(const Register& rd, const Register& rn, int immr, 1295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int imms) { 1296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rd.Is64Bits() || rn.Is32Bits()); 1297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instr N = SF(rd) >> (kSFOffset - kBitfieldNOffset); 1298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(SF(rd) | SBFM | N | 1299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ImmR(immr, rd.SizeInBits()) | 1300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ImmS(imms, rn.SizeInBits()) | 1301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Rn(rn) | Rd(rd)); 1302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::ubfm(const Register& rd, const Register& rn, int immr, 1306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int imms) { 1307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rd.SizeInBits() == rn.SizeInBits()); 1308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instr N = SF(rd) >> (kSFOffset - kBitfieldNOffset); 1309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(SF(rd) | UBFM | N | 1310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ImmR(immr, rd.SizeInBits()) | 1311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ImmS(imms, rn.SizeInBits()) | 1312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Rn(rn) | Rd(rd)); 1313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::extr(const Register& rd, const Register& rn, const Register& rm, 1317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int lsb) { 1318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rd.SizeInBits() == rn.SizeInBits()); 1319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rd.SizeInBits() == rm.SizeInBits()); 1320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instr N = SF(rd) >> (kSFOffset - kBitfieldNOffset); 1321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(SF(rd) | EXTR | N | Rm(rm) | 1322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ImmS(lsb, rn.SizeInBits()) | Rn(rn) | Rd(rd)); 1323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::csel(const Register& rd, 1327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 1328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rm, 1329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition cond) { 1330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ConditionalSelect(rd, rn, rm, cond, CSEL); 1331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::csinc(const Register& rd, 1335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 1336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rm, 1337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition cond) { 1338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ConditionalSelect(rd, rn, rm, cond, CSINC); 1339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::csinv(const Register& rd, 1343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 1344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rm, 1345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition cond) { 1346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ConditionalSelect(rd, rn, rm, cond, CSINV); 1347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::csneg(const Register& rd, 1351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 1352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rm, 1353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition cond) { 1354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ConditionalSelect(rd, rn, rm, cond, CSNEG); 1355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::cset(const Register &rd, Condition cond) { 1359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((cond != al) && (cond != nv)); 1360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register zr = AppropriateZeroRegFor(rd); 1361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch csinc(rd, zr, zr, NegateCondition(cond)); 1362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::csetm(const Register &rd, Condition cond) { 1366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((cond != al) && (cond != nv)); 1367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register zr = AppropriateZeroRegFor(rd); 1368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch csinv(rd, zr, zr, NegateCondition(cond)); 1369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::cinc(const Register &rd, const Register &rn, Condition cond) { 1373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((cond != al) && (cond != nv)); 1374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch csinc(rd, rn, rn, NegateCondition(cond)); 1375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::cinv(const Register &rd, const Register &rn, Condition cond) { 1379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((cond != al) && (cond != nv)); 1380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch csinv(rd, rn, rn, NegateCondition(cond)); 1381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::cneg(const Register &rd, const Register &rn, Condition cond) { 1385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((cond != al) && (cond != nv)); 1386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch csneg(rd, rn, rn, NegateCondition(cond)); 1387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ConditionalSelect(const Register& rd, 1391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 1392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rm, 1393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition cond, 1394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ConditionalSelectOp op) { 1395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rd.SizeInBits() == rn.SizeInBits()); 1396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rd.SizeInBits() == rm.SizeInBits()); 1397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(SF(rd) | op | Rm(rm) | Cond(cond) | Rn(rn) | Rd(rd)); 1398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ccmn(const Register& rn, 1402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operand& operand, 1403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StatusFlags nzcv, 1404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition cond) { 1405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ConditionalCompare(rn, operand, nzcv, cond, CCMN); 1406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ccmp(const Register& rn, 1410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operand& operand, 1411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StatusFlags nzcv, 1412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition cond) { 1413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ConditionalCompare(rn, operand, nzcv, cond, CCMP); 1414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::DataProcessing3Source(const Register& rd, 1418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 1419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rm, 1420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& ra, 1421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DataProcessing3SourceOp op) { 1422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(SF(rd) | op | Rm(rm) | Ra(ra) | Rn(rn) | Rd(rd)); 1423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::mul(const Register& rd, 1427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 1428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rm) { 1429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(AreSameSizeAndType(rd, rn, rm)); 1430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register zr = AppropriateZeroRegFor(rn); 1431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DataProcessing3Source(rd, rn, rm, zr, MADD); 1432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::madd(const Register& rd, 1436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 1437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rm, 1438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& ra) { 1439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(AreSameSizeAndType(rd, rn, rm, ra)); 1440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DataProcessing3Source(rd, rn, rm, ra, MADD); 1441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::mneg(const Register& rd, 1445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 1446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rm) { 1447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(AreSameSizeAndType(rd, rn, rm)); 1448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register zr = AppropriateZeroRegFor(rn); 1449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DataProcessing3Source(rd, rn, rm, zr, MSUB); 1450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::msub(const Register& rd, 1454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 1455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rm, 1456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& ra) { 1457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(AreSameSizeAndType(rd, rn, rm, ra)); 1458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DataProcessing3Source(rd, rn, rm, ra, MSUB); 1459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::smaddl(const Register& rd, 1463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 1464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rm, 1465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& ra) { 1466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rd.Is64Bits() && ra.Is64Bits()); 1467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rn.Is32Bits() && rm.Is32Bits()); 1468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DataProcessing3Source(rd, rn, rm, ra, SMADDL_x); 1469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::smsubl(const Register& rd, 1473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 1474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rm, 1475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& ra) { 1476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rd.Is64Bits() && ra.Is64Bits()); 1477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rn.Is32Bits() && rm.Is32Bits()); 1478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DataProcessing3Source(rd, rn, rm, ra, SMSUBL_x); 1479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::umaddl(const Register& rd, 1483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 1484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rm, 1485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& ra) { 1486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rd.Is64Bits() && ra.Is64Bits()); 1487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rn.Is32Bits() && rm.Is32Bits()); 1488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DataProcessing3Source(rd, rn, rm, ra, UMADDL_x); 1489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::umsubl(const Register& rd, 1493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 1494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rm, 1495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& ra) { 1496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rd.Is64Bits() && ra.Is64Bits()); 1497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rn.Is32Bits() && rm.Is32Bits()); 1498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DataProcessing3Source(rd, rn, rm, ra, UMSUBL_x); 1499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::smull(const Register& rd, 1503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 1504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rm) { 1505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rd.Is64Bits()); 1506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rn.Is32Bits() && rm.Is32Bits()); 1507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DataProcessing3Source(rd, rn, rm, xzr, SMADDL_x); 1508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::smulh(const Register& rd, 1512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 1513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rm) { 1514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(AreSameSizeAndType(rd, rn, rm)); 1515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DataProcessing3Source(rd, rn, rm, xzr, SMULH_x); 1516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::sdiv(const Register& rd, 1520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 1521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rm) { 1522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rd.SizeInBits() == rn.SizeInBits()); 1523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rd.SizeInBits() == rm.SizeInBits()); 1524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(SF(rd) | SDIV | Rm(rm) | Rn(rn) | Rd(rd)); 1525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::udiv(const Register& rd, 1529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 1530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rm) { 1531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rd.SizeInBits() == rn.SizeInBits()); 1532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rd.SizeInBits() == rm.SizeInBits()); 1533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(SF(rd) | UDIV | Rm(rm) | Rn(rn) | Rd(rd)); 1534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::rbit(const Register& rd, 1538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn) { 1539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DataProcessing1Source(rd, rn, RBIT); 1540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::rev16(const Register& rd, 1544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn) { 1545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DataProcessing1Source(rd, rn, REV16); 1546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::rev32(const Register& rd, 1550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn) { 1551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rd.Is64Bits()); 1552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DataProcessing1Source(rd, rn, REV); 1553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::rev(const Register& rd, 1557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn) { 1558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DataProcessing1Source(rd, rn, rd.Is64Bits() ? REV_x : REV_w); 1559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::clz(const Register& rd, 1563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn) { 1564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DataProcessing1Source(rd, rn, CLZ); 1565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::cls(const Register& rd, 1569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn) { 1570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DataProcessing1Source(rd, rn, CLS); 1571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ldp(const CPURegister& rt, 1575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const CPURegister& rt2, 1576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const MemOperand& src) { 1577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadStorePair(rt, rt2, src, LoadPairOpFor(rt, rt2)); 1578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::stp(const CPURegister& rt, 1582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const CPURegister& rt2, 1583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const MemOperand& dst) { 1584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadStorePair(rt, rt2, dst, StorePairOpFor(rt, rt2)); 1585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ldpsw(const Register& rt, 1589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rt2, 1590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const MemOperand& src) { 1591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rt.Is64Bits()); 1592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadStorePair(rt, rt2, src, LDPSW_x); 1593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::LoadStorePair(const CPURegister& rt, 1597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const CPURegister& rt2, 1598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const MemOperand& addr, 1599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadStorePairOp op) { 1600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 'rt' and 'rt2' can only be aliased for stores. 1601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(((op & LoadStorePairLBit) == 0) || !rt.Is(rt2)); 1602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(AreSameSizeAndType(rt, rt2)); 1603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsImmLSPair(addr.offset(), CalcLSPairDataSize(op))); 1604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int offset = static_cast<int>(addr.offset()); 1605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instr memop = op | Rt(rt) | Rt2(rt2) | RnSP(addr.base()) | 1607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ImmLSPair(offset, CalcLSPairDataSize(op)); 1608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instr addrmodeop; 1610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (addr.IsImmediateOffset()) { 1611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addrmodeop = LoadStorePairOffsetFixed; 1612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Pre-index and post-index modes. 1614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!rt.Is(addr.base())); 1615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!rt2.Is(addr.base())); 1616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(addr.offset() != 0); 1617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (addr.IsPreIndex()) { 1618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addrmodeop = LoadStorePairPreIndexFixed; 1619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(addr.IsPostIndex()); 1621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addrmodeop = LoadStorePairPostIndexFixed; 1622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(addrmodeop | memop); 1625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Memory instructions. 1629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ldrb(const Register& rt, const MemOperand& src) { 1630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadStore(rt, src, LDRB_w); 1631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::strb(const Register& rt, const MemOperand& dst) { 1635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadStore(rt, dst, STRB_w); 1636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ldrsb(const Register& rt, const MemOperand& src) { 1640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadStore(rt, src, rt.Is64Bits() ? LDRSB_x : LDRSB_w); 1641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ldrh(const Register& rt, const MemOperand& src) { 1645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadStore(rt, src, LDRH_w); 1646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::strh(const Register& rt, const MemOperand& dst) { 1650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadStore(rt, dst, STRH_w); 1651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ldrsh(const Register& rt, const MemOperand& src) { 1655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadStore(rt, src, rt.Is64Bits() ? LDRSH_x : LDRSH_w); 1656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ldr(const CPURegister& rt, const MemOperand& src) { 1660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadStore(rt, src, LoadOpFor(rt)); 1661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::str(const CPURegister& rt, const MemOperand& src) { 1665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadStore(rt, src, StoreOpFor(rt)); 1666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ldrsw(const Register& rt, const MemOperand& src) { 1670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rt.Is64Bits()); 1671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadStore(rt, src, LDRSW_x); 1672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ldr_pcrel(const CPURegister& rt, int imm19) { 1676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The pattern 'ldr xzr, #offset' is used to indicate the beginning of a 1677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // constant pool. It should not be emitted. 1678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!rt.IsZero()); 1679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(LoadLiteralOpFor(rt) | ImmLLiteral(imm19) | Rt(rt)); 1680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ldr(const CPURegister& rt, const Immediate& imm) { 1684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Currently we only support 64-bit literals. 1685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rt.Is64Bits()); 1686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RecordRelocInfo(imm.rmode(), imm.value()); 1688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BlockConstPoolFor(1); 1689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The load will be patched when the constpool is emitted, patching code 1690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // expect a load literal with offset 0. 1691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ldr_pcrel(rt, 0); 1692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 169421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochvoid Assembler::ldar(const Register& rt, const Register& rn) { 169521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch DCHECK(rn.Is64Bits()); 169621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch LoadStoreAcquireReleaseOp op = rt.Is32Bits() ? LDAR_w : LDAR_x; 169721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Emit(op | Rs(x31) | Rt2(x31) | Rn(rn) | Rt(rt)); 169821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 169921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 170021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochvoid Assembler::ldaxr(const Register& rt, const Register& rn) { 170121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch DCHECK(rn.Is64Bits()); 170221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch LoadStoreAcquireReleaseOp op = rt.Is32Bits() ? LDAXR_w : LDAXR_x; 170321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Emit(op | Rs(x31) | Rt2(x31) | Rn(rn) | Rt(rt)); 170421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 170521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 170621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochvoid Assembler::stlr(const Register& rt, const Register& rn) { 170721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch DCHECK(rn.Is64Bits()); 170821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch LoadStoreAcquireReleaseOp op = rt.Is32Bits() ? STLR_w : STLR_x; 170921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Emit(op | Rs(x31) | Rt2(x31) | Rn(rn) | Rt(rt)); 171021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 171121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 171221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochvoid Assembler::stlxr(const Register& rs, const Register& rt, 171321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch const Register& rn) { 171421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch DCHECK(rs.Is32Bits()); 171521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch DCHECK(rn.Is64Bits()); 171621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch LoadStoreAcquireReleaseOp op = rt.Is32Bits() ? STLXR_w : STLXR_x; 171721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Emit(op | Rs(rs) | Rt2(x31) | Rn(rn) | Rt(rt)); 171821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 171921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 172021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochvoid Assembler::ldarb(const Register& rt, const Register& rn) { 172121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch DCHECK(rt.Is32Bits()); 172221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch DCHECK(rn.Is64Bits()); 172321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Emit(LDAR_b | Rs(x31) | Rt2(x31) | Rn(rn) | Rt(rt)); 172421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 172521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 172621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochvoid Assembler::ldaxrb(const Register& rt, const Register& rn) { 172721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch DCHECK(rt.Is32Bits()); 172821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch DCHECK(rn.Is64Bits()); 172921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Emit(LDAXR_b | Rs(x31) | Rt2(x31) | Rn(rn) | Rt(rt)); 173021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 173121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 173221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochvoid Assembler::stlrb(const Register& rt, const Register& rn) { 173321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch DCHECK(rt.Is32Bits()); 173421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch DCHECK(rn.Is64Bits()); 173521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Emit(STLR_b | Rs(x31) | Rt2(x31) | Rn(rn) | Rt(rt)); 173621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 173721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 173821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochvoid Assembler::stlxrb(const Register& rs, const Register& rt, 173921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch const Register& rn) { 174021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch DCHECK(rs.Is32Bits()); 174121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch DCHECK(rt.Is32Bits()); 174221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch DCHECK(rn.Is64Bits()); 174321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Emit(STLXR_b | Rs(rs) | Rt2(x31) | Rn(rn) | Rt(rt)); 174421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 174521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 174621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochvoid Assembler::ldarh(const Register& rt, const Register& rn) { 174721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch DCHECK(rt.Is32Bits()); 174821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch DCHECK(rn.Is64Bits()); 174921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Emit(LDAR_h | Rs(x31) | Rt2(x31) | Rn(rn) | Rt(rt)); 175021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 175121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 175221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochvoid Assembler::ldaxrh(const Register& rt, const Register& rn) { 175321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch DCHECK(rt.Is32Bits()); 175421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch DCHECK(rn.Is64Bits()); 175521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Emit(LDAXR_h | Rs(x31) | Rt2(x31) | Rn(rn) | Rt(rt)); 175621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 175721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 175821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochvoid Assembler::stlrh(const Register& rt, const Register& rn) { 175921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch DCHECK(rt.Is32Bits()); 176021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch DCHECK(rn.Is64Bits()); 176121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Emit(STLR_h | Rs(x31) | Rt2(x31) | Rn(rn) | Rt(rt)); 176221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 176321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 176421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochvoid Assembler::stlxrh(const Register& rs, const Register& rt, 176521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch const Register& rn) { 176621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch DCHECK(rs.Is32Bits()); 176721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch DCHECK(rt.Is32Bits()); 176821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch DCHECK(rn.Is64Bits()); 176921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Emit(STLXR_h | Rs(rs) | Rt2(x31) | Rn(rn) | Rt(rt)); 177021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 1771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::mov(const Register& rd, const Register& rm) { 1773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Moves involving the stack pointer are encoded as add immediate with 1774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // second operand of zero. Otherwise, orr with first operand zr is 1775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // used. 1776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (rd.IsSP() || rm.IsSP()) { 1777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch add(rd, rm, 0); 1778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch orr(rd, AppropriateZeroRegFor(rd), rm); 1780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::mvn(const Register& rd, const Operand& operand) { 1785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch orn(rd, AppropriateZeroRegFor(rd), operand); 1786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::mrs(const Register& rt, SystemRegister sysreg) { 1790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rt.Is64Bits()); 1791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(MRS | ImmSystemRegister(sysreg) | Rt(rt)); 1792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::msr(SystemRegister sysreg, const Register& rt) { 1796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rt.Is64Bits()); 1797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(MSR | Rt(rt) | ImmSystemRegister(sysreg)); 1798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::hint(SystemHint code) { 1802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(HINT | ImmHint(code) | Rt(xzr)); 1803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dmb(BarrierDomain domain, BarrierType type) { 1807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(DMB | ImmBarrierDomain(domain) | ImmBarrierType(type)); 1808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::dsb(BarrierDomain domain, BarrierType type) { 1812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(DSB | ImmBarrierDomain(domain) | ImmBarrierType(type)); 1813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::isb() { 1817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(ISB | ImmBarrierDomain(FullSystem) | ImmBarrierType(BarrierAll)); 1818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::fmov(FPRegister fd, double imm) { 1822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(fd.Is64Bits()); 1823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsImmFP64(imm)); 1824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(FMOV_d_imm | Rd(fd) | ImmFP64(imm)); 1825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::fmov(FPRegister fd, float imm) { 1829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(fd.Is32Bits()); 1830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsImmFP32(imm)); 1831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(FMOV_s_imm | Rd(fd) | ImmFP32(imm)); 1832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::fmov(Register rd, FPRegister fn) { 1836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rd.SizeInBits() == fn.SizeInBits()); 1837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPIntegerConvertOp op = rd.Is32Bits() ? FMOV_ws : FMOV_xd; 1838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(op | Rd(rd) | Rn(fn)); 1839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::fmov(FPRegister fd, Register rn) { 1843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(fd.SizeInBits() == rn.SizeInBits()); 1844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPIntegerConvertOp op = fd.Is32Bits() ? FMOV_sw : FMOV_dx; 1845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(op | Rd(fd) | Rn(rn)); 1846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::fmov(FPRegister fd, FPRegister fn) { 1850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(fd.SizeInBits() == fn.SizeInBits()); 1851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(FPType(fd) | FMOV | Rd(fd) | Rn(fn)); 1852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::fadd(const FPRegister& fd, 1856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fn, 1857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fm) { 1858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPDataProcessing2Source(fd, fn, fm, FADD); 1859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::fsub(const FPRegister& fd, 1863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fn, 1864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fm) { 1865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPDataProcessing2Source(fd, fn, fm, FSUB); 1866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::fmul(const FPRegister& fd, 1870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fn, 1871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fm) { 1872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPDataProcessing2Source(fd, fn, fm, FMUL); 1873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::fmadd(const FPRegister& fd, 1877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fn, 1878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fm, 1879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fa) { 1880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPDataProcessing3Source(fd, fn, fm, fa, fd.Is32Bits() ? FMADD_s : FMADD_d); 1881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::fmsub(const FPRegister& fd, 1885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fn, 1886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fm, 1887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fa) { 1888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPDataProcessing3Source(fd, fn, fm, fa, fd.Is32Bits() ? FMSUB_s : FMSUB_d); 1889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::fnmadd(const FPRegister& fd, 1893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fn, 1894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fm, 1895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fa) { 1896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPDataProcessing3Source(fd, fn, fm, fa, fd.Is32Bits() ? FNMADD_s : FNMADD_d); 1897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::fnmsub(const FPRegister& fd, 1901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fn, 1902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fm, 1903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fa) { 1904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPDataProcessing3Source(fd, fn, fm, fa, fd.Is32Bits() ? FNMSUB_s : FNMSUB_d); 1905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::fdiv(const FPRegister& fd, 1909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fn, 1910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fm) { 1911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPDataProcessing2Source(fd, fn, fm, FDIV); 1912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::fmax(const FPRegister& fd, 1916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fn, 1917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fm) { 1918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPDataProcessing2Source(fd, fn, fm, FMAX); 1919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::fmaxnm(const FPRegister& fd, 1923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fn, 1924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fm) { 1925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPDataProcessing2Source(fd, fn, fm, FMAXNM); 1926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::fmin(const FPRegister& fd, 1930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fn, 1931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fm) { 1932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPDataProcessing2Source(fd, fn, fm, FMIN); 1933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::fminnm(const FPRegister& fd, 1937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fn, 1938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fm) { 1939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPDataProcessing2Source(fd, fn, fm, FMINNM); 1940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::fabs(const FPRegister& fd, 1944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fn) { 1945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(fd.SizeInBits() == fn.SizeInBits()); 1946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPDataProcessing1Source(fd, fn, FABS); 1947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::fneg(const FPRegister& fd, 1951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fn) { 1952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(fd.SizeInBits() == fn.SizeInBits()); 1953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPDataProcessing1Source(fd, fn, FNEG); 1954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::fsqrt(const FPRegister& fd, 1958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fn) { 1959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(fd.SizeInBits() == fn.SizeInBits()); 1960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPDataProcessing1Source(fd, fn, FSQRT); 1961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::frinta(const FPRegister& fd, 1965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fn) { 1966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(fd.SizeInBits() == fn.SizeInBits()); 1967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPDataProcessing1Source(fd, fn, FRINTA); 1968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::frintm(const FPRegister& fd, 1972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fn) { 1973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(fd.SizeInBits() == fn.SizeInBits()); 1974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPDataProcessing1Source(fd, fn, FRINTM); 1975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::frintn(const FPRegister& fd, 1979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fn) { 1980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(fd.SizeInBits() == fn.SizeInBits()); 1981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPDataProcessing1Source(fd, fn, FRINTN); 1982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1985958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid Assembler::frintp(const FPRegister& fd, const FPRegister& fn) { 1986958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(fd.SizeInBits() == fn.SizeInBits()); 1987958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FPDataProcessing1Source(fd, fn, FRINTP); 1988958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1989958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1990958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::frintz(const FPRegister& fd, 1992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fn) { 1993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(fd.SizeInBits() == fn.SizeInBits()); 1994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPDataProcessing1Source(fd, fn, FRINTZ); 1995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::fcmp(const FPRegister& fn, 1999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fm) { 2000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(fn.SizeInBits() == fm.SizeInBits()); 2001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(FPType(fn) | FCMP | Rm(fm) | Rn(fn)); 2002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::fcmp(const FPRegister& fn, 2006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double value) { 2007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch USE(value); 2008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Although the fcmp instruction can strictly only take an immediate value of 2009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // +0.0, we don't need to check for -0.0 because the sign of 0.0 doesn't 2010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // affect the result of the comparison. 2011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(value == 0.0); 2012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(FPType(fn) | FCMP_zero | Rn(fn)); 2013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::fccmp(const FPRegister& fn, 2017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fm, 2018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StatusFlags nzcv, 2019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition cond) { 2020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(fn.SizeInBits() == fm.SizeInBits()); 2021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(FPType(fn) | FCCMP | Rm(fm) | Cond(cond) | Rn(fn) | Nzcv(nzcv)); 2022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::fcsel(const FPRegister& fd, 2026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fn, 2027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fm, 2028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition cond) { 2029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(fd.SizeInBits() == fn.SizeInBits()); 2030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(fd.SizeInBits() == fm.SizeInBits()); 2031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(FPType(fd) | FCSEL | Rm(fm) | Cond(cond) | Rn(fn) | Rd(fd)); 2032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::FPConvertToInt(const Register& rd, 2036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fn, 2037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPIntegerConvertOp op) { 2038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(SF(rd) | FPType(fn) | op | Rn(fn) | Rd(rd)); 2039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::fcvt(const FPRegister& fd, 2043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fn) { 2044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (fd.Is64Bits()) { 2045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Convert float to double. 2046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(fn.Is32Bits()); 2047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPDataProcessing1Source(fd, fn, FCVT_ds); 2048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Convert double to float. 2050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(fn.Is64Bits()); 2051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPDataProcessing1Source(fd, fn, FCVT_sd); 2052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::fcvtau(const Register& rd, const FPRegister& fn) { 2057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPConvertToInt(rd, fn, FCVTAU); 2058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::fcvtas(const Register& rd, const FPRegister& fn) { 2062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPConvertToInt(rd, fn, FCVTAS); 2063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::fcvtmu(const Register& rd, const FPRegister& fn) { 2067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPConvertToInt(rd, fn, FCVTMU); 2068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::fcvtms(const Register& rd, const FPRegister& fn) { 2072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPConvertToInt(rd, fn, FCVTMS); 2073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::fcvtnu(const Register& rd, const FPRegister& fn) { 2077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPConvertToInt(rd, fn, FCVTNU); 2078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::fcvtns(const Register& rd, const FPRegister& fn) { 2082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPConvertToInt(rd, fn, FCVTNS); 2083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::fcvtzu(const Register& rd, const FPRegister& fn) { 2087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPConvertToInt(rd, fn, FCVTZU); 2088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::fcvtzs(const Register& rd, const FPRegister& fn) { 2092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPConvertToInt(rd, fn, FCVTZS); 2093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::scvtf(const FPRegister& fd, 2097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 2098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned fbits) { 2099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (fbits == 0) { 2100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(SF(rn) | FPType(fd) | SCVTF | Rn(rn) | Rd(fd)); 2101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(SF(rn) | FPType(fd) | SCVTF_fixed | FPScale(64 - fbits) | Rn(rn) | 2103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Rd(fd)); 2104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ucvtf(const FPRegister& fd, 2109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 2110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned fbits) { 2111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (fbits == 0) { 2112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(SF(rn) | FPType(fd) | UCVTF | Rn(rn) | Rd(fd)); 2113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(SF(rn) | FPType(fd) | UCVTF_fixed | FPScale(64 - fbits) | Rn(rn) | 2115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Rd(fd)); 2116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::dcptr(Label* label) { 2121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE); 2122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (label->is_bound()) { 2123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The label is bound, so it does not need to be updated and the internal 2124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // reference should be emitted. 2125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 2126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // In this case, label->pos() returns the offset of the label from the 2127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // start of the buffer. 2128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch internal_reference_positions_.push_back(pc_offset()); 2129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch dc64(reinterpret_cast<uintptr_t>(buffer_ + label->pos())); 2130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int32_t offset; 2132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (label->is_linked()) { 2133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The label is linked, so the internal reference should be added 2134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // onto the end of the label's link chain. 2135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 2136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // In this case, label->pos() returns the offset of the last linked 2137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // instruction from the start of the buffer. 2138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch offset = label->pos() - pc_offset(); 2139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(offset != kStartOfLabelLinkChain); 2140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The label is unused, so it now becomes linked and the internal 2142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // reference is at the start of the new link chain. 2143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch offset = kStartOfLabelLinkChain; 2144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The instruction at pc is now the last link in the label's chain. 2146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch label->link_to(pc_offset()); 2147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Traditionally the offset to the previous instruction in the chain is 2149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // encoded in the instruction payload (e.g. branch range) but internal 2150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // references are not instructions so while unbound they are encoded as 2151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // two consecutive brk instructions. The two 16-bit immediates are used 2152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // to encode the offset. 2153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch offset >>= kInstructionSizeLog2; 2154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(is_int32(offset)); 2155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t high16 = unsigned_bitextract_32(31, 16, offset); 2156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t low16 = unsigned_bitextract_32(15, 0, offset); 2157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch brk(high16); 2159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch brk(low16); 2160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Note: 2165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Below, a difference in case for the same letter indicates a 2166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// negated bit. 2167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// If b is 1, then B is 0. 2168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochInstr Assembler::ImmFP32(float imm) { 2169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsImmFP32(imm)); 2170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // bits: aBbb.bbbc.defg.h000.0000.0000.0000.0000 2171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t bits = float_to_rawbits(imm); 2172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // bit7: a000.0000 2173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t bit7 = ((bits >> 31) & 0x1) << 7; 2174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // bit6: 0b00.0000 2175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t bit6 = ((bits >> 29) & 0x1) << 6; 2176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // bit5_to_0: 00cd.efgh 2177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t bit5_to_0 = (bits >> 19) & 0x3f; 2178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return (bit7 | bit6 | bit5_to_0) << ImmFP_offset; 2180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochInstr Assembler::ImmFP64(double imm) { 2184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsImmFP64(imm)); 2185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // bits: aBbb.bbbb.bbcd.efgh.0000.0000.0000.0000 2186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 0000.0000.0000.0000.0000.0000.0000.0000 2187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint64_t bits = double_to_rawbits(imm); 2188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // bit7: a000.0000 2189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint64_t bit7 = ((bits >> 63) & 0x1) << 7; 2190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // bit6: 0b00.0000 2191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint64_t bit6 = ((bits >> 61) & 0x1) << 6; 2192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // bit5_to_0: 00cd.efgh 2193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint64_t bit5_to_0 = (bits >> 48) & 0x3f; 2194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return static_cast<Instr>((bit7 | bit6 | bit5_to_0) << ImmFP_offset); 2196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Code generation helpers. 2200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::MoveWide(const Register& rd, 2201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint64_t imm, 2202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int shift, 2203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MoveWideImmediateOp mov_op) { 2204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Ignore the top 32 bits of an immediate if we're moving to a W register. 2205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (rd.Is32Bits()) { 2206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check that the top 32 bits are zero (a positive 32-bit number) or top 2207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 33 bits are one (a negative 32-bit number, sign extended to 64 bits). 2208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(((imm >> kWRegSizeInBits) == 0) || 2209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ((imm >> (kWRegSizeInBits - 1)) == 0x1ffffffff)); 2210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch imm &= kWRegMask; 2211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (shift >= 0) { 2214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Explicit shift specified. 2215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((shift == 0) || (shift == 16) || (shift == 32) || (shift == 48)); 2216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rd.Is64Bits() || (shift == 0) || (shift == 16)); 2217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shift /= 16; 2218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Calculate a new immediate and shift combination to encode the immediate 2220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // argument. 2221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shift = 0; 2222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((imm & ~0xffffUL) == 0) { 2223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Nothing to do. 2224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if ((imm & ~(0xffffUL << 16)) == 0) { 2225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch imm >>= 16; 2226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shift = 1; 2227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if ((imm & ~(0xffffUL << 32)) == 0) { 2228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rd.Is64Bits()); 2229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch imm >>= 32; 2230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shift = 2; 2231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if ((imm & ~(0xffffUL << 48)) == 0) { 2232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rd.Is64Bits()); 2233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch imm >>= 48; 2234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shift = 3; 2235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_uint16(imm)); 2239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Emit(SF(rd) | MoveWideImmediateFixed | mov_op | Rd(rd) | 2241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ImmMoveWide(static_cast<int>(imm)) | ShiftMoveWide(shift)); 2242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::AddSub(const Register& rd, 2246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 2247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operand& operand, 2248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FlagsUpdate S, 2249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddSubOp op) { 2250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rd.SizeInBits() == rn.SizeInBits()); 2251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!operand.NeedsRelocation(this)); 2252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (operand.IsImmediate()) { 2253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int64_t immediate = operand.ImmediateValue(); 2254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsImmAddSub(immediate)); 2255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instr dest_reg = (S == SetFlags) ? Rd(rd) : RdSP(rd); 2256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(SF(rd) | AddSubImmediateFixed | op | Flags(S) | 2257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ImmAddSub(static_cast<int>(immediate)) | dest_reg | RnSP(rn)); 2258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (operand.IsShiftedRegister()) { 2259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(operand.reg().SizeInBits() == rd.SizeInBits()); 2260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(operand.shift() != ROR); 2261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // For instructions of the form: 2263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // add/sub wsp, <Wn>, <Wm> [, LSL #0-3 ] 2264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // add/sub <Wd>, wsp, <Wm> [, LSL #0-3 ] 2265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // add/sub wsp, wsp, <Wm> [, LSL #0-3 ] 2266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // adds/subs <Wd>, wsp, <Wm> [, LSL #0-3 ] 2267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // or their 64-bit register equivalents, convert the operand from shifted to 2268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // extended register mode, and emit an add/sub extended instruction. 2269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (rn.IsSP() || rd.IsSP()) { 2270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!(rd.IsSP() && (S == SetFlags))); 2271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DataProcExtendedRegister(rd, rn, operand.ToExtendedRegister(), S, 2272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddSubExtendedFixed | op); 2273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DataProcShiftedRegister(rd, rn, operand, S, AddSubShiftedFixed | op); 2275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(operand.IsExtendedRegister()); 2278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DataProcExtendedRegister(rd, rn, operand, S, AddSubExtendedFixed | op); 2279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::AddSubWithCarry(const Register& rd, 2284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 2285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operand& operand, 2286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FlagsUpdate S, 2287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddSubWithCarryOp op) { 2288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rd.SizeInBits() == rn.SizeInBits()); 2289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rd.SizeInBits() == operand.reg().SizeInBits()); 2290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(operand.IsShiftedRegister() && (operand.shift_amount() == 0)); 2291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!operand.NeedsRelocation(this)); 2292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(SF(rd) | op | Flags(S) | Rm(operand.reg()) | Rn(rn) | Rd(rd)); 2293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::hlt(int code) { 2297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_uint16(code)); 2298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(HLT | ImmException(code)); 2299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::brk(int code) { 2303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_uint16(code)); 2304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(BRK | ImmException(code)); 2305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::EmitStringData(const char* string) { 2309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t len = strlen(string) + 1; 2310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(RoundUp(len, kInstructionSize) <= static_cast<size_t>(kGap)); 2311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch EmitData(string, static_cast<int>(len)); 2312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Pad with NULL characters until pc_ is aligned. 2313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char pad[] = {'\0', '\0', '\0', '\0'}; 2314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(sizeof(pad) == kInstructionSize); 2315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EmitData(pad, RoundUp(pc_offset(), kInstructionSize) - pc_offset()); 2316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::debug(const char* message, uint32_t code, Instr params) { 2320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef USE_SIMULATOR 2321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Don't generate simulator specific code if we are building a snapshot, which 2322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // might be run on real hardware. 2323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!serializer_enabled()) { 2324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The arguments to the debug marker need to be contiguous in memory, so 2325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // make sure we don't try to emit pools. 2326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BlockPoolsScope scope(this); 2327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label start; 2329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&start); 2330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Refer to instructions-arm64.h for a description of the marker and its 2332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // arguments. 2333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch hlt(kImmExceptionIsDebug); 2334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SizeOfCodeGeneratedSince(&start) == kDebugCodeOffset); 2335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch dc32(code); 2336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SizeOfCodeGeneratedSince(&start) == kDebugParamsOffset); 2337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch dc32(params); 2338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SizeOfCodeGeneratedSince(&start) == kDebugMessageOffset); 2339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EmitStringData(message); 2340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch hlt(kImmExceptionIsUnreachable); 2341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 2343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Fall through if Serializer is enabled. 2345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 2346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (params & BREAK) { 2348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch hlt(kImmExceptionIsDebug); 2349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::Logical(const Register& rd, 2354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 2355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operand& operand, 2356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LogicalOp op) { 2357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rd.SizeInBits() == rn.SizeInBits()); 2358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!operand.NeedsRelocation(this)); 2359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (operand.IsImmediate()) { 2360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int64_t immediate = operand.ImmediateValue(); 2361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned reg_size = rd.SizeInBits(); 2362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(immediate != 0); 2364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(immediate != -1); 2365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rd.Is64Bits() || is_uint32(immediate)); 2366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the operation is NOT, invert the operation and immediate. 2368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((op & NOT) == NOT) { 2369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch op = static_cast<LogicalOp>(op & ~NOT); 2370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch immediate = rd.Is64Bits() ? ~immediate : (~immediate & kWRegMask); 2371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned n, imm_s, imm_r; 2374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsImmLogical(immediate, reg_size, &n, &imm_s, &imm_r)) { 2375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Immediate can be encoded in the instruction. 2376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LogicalImmediate(rd, rn, n, imm_s, imm_r, op); 2377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This case is handled in the macro assembler. 2379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 2380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(operand.IsShiftedRegister()); 2383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(operand.reg().SizeInBits() == rd.SizeInBits()); 2384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instr dp_op = static_cast<Instr>(op | LogicalShiftedFixed); 2385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DataProcShiftedRegister(rd, rn, operand, LeaveFlags, dp_op); 2386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::LogicalImmediate(const Register& rd, 2391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 2392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned n, 2393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned imm_s, 2394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned imm_r, 2395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LogicalOp op) { 2396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned reg_size = rd.SizeInBits(); 2397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instr dest_reg = (op == ANDS) ? Rd(rd) : RdSP(rd); 2398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(SF(rd) | LogicalImmediateFixed | op | BitN(n, reg_size) | 2399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ImmSetBits(imm_s, reg_size) | ImmRotate(imm_r, reg_size) | dest_reg | 2400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Rn(rn)); 2401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::ConditionalCompare(const Register& rn, 2405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operand& operand, 2406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StatusFlags nzcv, 2407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition cond, 2408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ConditionalCompareOp op) { 2409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instr ccmpop; 2410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!operand.NeedsRelocation(this)); 2411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (operand.IsImmediate()) { 2412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int64_t immediate = operand.ImmediateValue(); 2413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsImmConditionalCompare(immediate)); 2414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ccmpop = ConditionalCompareImmediateFixed | op | 2415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ImmCondCmp(static_cast<unsigned>(immediate)); 2416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(operand.IsShiftedRegister() && (operand.shift_amount() == 0)); 2418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ccmpop = ConditionalCompareRegisterFixed | op | Rm(operand.reg()); 2419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(SF(rn) | ccmpop | Cond(cond) | Rn(rn) | Nzcv(nzcv)); 2421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::DataProcessing1Source(const Register& rd, 2425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 2426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DataProcessing1SourceOp op) { 2427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rd.SizeInBits() == rn.SizeInBits()); 2428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(SF(rn) | op | Rn(rn) | Rd(rd)); 2429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::FPDataProcessing1Source(const FPRegister& fd, 2433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fn, 2434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPDataProcessing1SourceOp op) { 2435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(FPType(fn) | op | Rn(fn) | Rd(fd)); 2436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::FPDataProcessing2Source(const FPRegister& fd, 2440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fn, 2441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fm, 2442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPDataProcessing2SourceOp op) { 2443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(fd.SizeInBits() == fn.SizeInBits()); 2444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(fd.SizeInBits() == fm.SizeInBits()); 2445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(FPType(fd) | op | Rm(fm) | Rn(fn) | Rd(fd)); 2446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::FPDataProcessing3Source(const FPRegister& fd, 2450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fn, 2451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fm, 2452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const FPRegister& fa, 2453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FPDataProcessing3SourceOp op) { 2454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(AreSameSizeAndType(fd, fn, fm, fa)); 2455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(FPType(fd) | op | Rm(fm) | Rn(fn) | Rd(fd) | Ra(fa)); 2456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::EmitShift(const Register& rd, 2460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 2461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Shift shift, 2462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned shift_amount) { 2463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (shift) { 2464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LSL: 2465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch lsl(rd, rn, shift_amount); 2466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LSR: 2468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch lsr(rd, rn, shift_amount); 2469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case ASR: 2471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch asr(rd, rn, shift_amount); 2472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case ROR: 2474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ror(rd, rn, shift_amount); 2475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 2477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 2478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::EmitExtendShift(const Register& rd, 2483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 2484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Extend extend, 2485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned left_shift) { 2486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rd.SizeInBits() >= rn.SizeInBits()); 2487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned reg_size = rd.SizeInBits(); 2488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Use the correct size of register. 2489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register rn_ = Register::Create(rn.code(), rd.SizeInBits()); 2490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Bits extracted are high_bit:0. 2491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned high_bit = (8 << (extend & 0x3)) - 1; 2492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Number of bits left in the result that are not introduced by the shift. 2493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned non_shift_bits = (reg_size - left_shift) & (reg_size - 1); 2494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((non_shift_bits > high_bit) || (non_shift_bits == 0)) { 2496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (extend) { 2497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case UXTB: 2498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case UXTH: 2499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case UXTW: ubfm(rd, rn_, non_shift_bits, high_bit); break; 2500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case SXTB: 2501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case SXTH: 2502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case SXTW: sbfm(rd, rn_, non_shift_bits, high_bit); break; 2503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case UXTX: 2504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case SXTX: { 2505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rn.SizeInBits() == kXRegSizeInBits); 2506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Nothing to extend. Just shift. 2507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch lsl(rd, rn_, left_shift); 2508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: UNREACHABLE(); 2511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // No need to extend as the extended bits would be shifted away. 2514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch lsl(rd, rn_, left_shift); 2515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::DataProcShiftedRegister(const Register& rd, 2520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 2521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operand& operand, 2522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FlagsUpdate S, 2523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instr op) { 2524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(operand.IsShiftedRegister()); 2525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rn.Is64Bits() || (rn.Is32Bits() && is_uint5(operand.shift_amount()))); 2526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!operand.NeedsRelocation(this)); 2527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(SF(rd) | op | Flags(S) | 2528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ShiftDP(operand.shift()) | ImmDPShift(operand.shift_amount()) | 2529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Rm(operand.reg()) | Rn(rn) | Rd(rd)); 2530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::DataProcExtendedRegister(const Register& rd, 2534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Register& rn, 2535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operand& operand, 2536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FlagsUpdate S, 2537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instr op) { 2538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!operand.NeedsRelocation(this)); 2539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instr dest_reg = (S == SetFlags) ? Rd(rd) : RdSP(rd); 2540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(SF(rd) | op | Flags(S) | Rm(operand.reg()) | 2541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExtendMode(operand.extend()) | ImmExtendShift(operand.shift_amount()) | 2542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch dest_reg | RnSP(rn)); 2543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsImmAddSub(int64_t immediate) { 2547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return is_uint12(immediate) || 2548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (is_uint12(immediate >> 12) && ((immediate & 0xfff) == 0)); 2549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::LoadStore(const CPURegister& rt, 2552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const MemOperand& addr, 2553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadStoreOp op) { 2554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instr memop = op | Rt(rt) | RnSP(addr.base()); 2555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (addr.IsImmediateOffset()) { 2557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LSDataSize size = CalcLSDataSize(op); 2558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsImmLSScaled(addr.offset(), size)) { 2559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int offset = static_cast<int>(addr.offset()); 2560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Use the scaled addressing mode. 2561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(LoadStoreUnsignedOffsetFixed | memop | 2562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ImmLSUnsigned(offset >> size)); 2563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (IsImmLSUnscaled(addr.offset())) { 2564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int offset = static_cast<int>(addr.offset()); 2565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Use the unscaled addressing mode. 2566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(LoadStoreUnscaledOffsetFixed | memop | ImmLS(offset)); 2567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This case is handled in the macro assembler. 2569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 2570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (addr.IsRegisterOffset()) { 2572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Extend ext = addr.extend(); 2573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Shift shift = addr.shift(); 2574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned shift_amount = addr.shift_amount(); 2575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // LSL is encoded in the option field as UXTX. 2577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (shift == LSL) { 2578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ext = UXTX; 2579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Shifts are encoded in one bit, indicating a left shift by the memory 2582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // access size. 2583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((shift_amount == 0) || 2584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (shift_amount == static_cast<unsigned>(CalcLSDataSize(op)))); 2585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(LoadStoreRegisterOffsetFixed | memop | Rm(addr.regoffset()) | 2586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExtendMode(ext) | ImmShiftLS((shift_amount > 0) ? 1 : 0)); 2587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Pre-index and post-index modes. 2589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!rt.Is(addr.base())); 2590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsImmLSUnscaled(addr.offset())) { 2591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int offset = static_cast<int>(addr.offset()); 2592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (addr.IsPreIndex()) { 2593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(LoadStorePreIndexFixed | memop | ImmLS(offset)); 2594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(addr.IsPostIndex()); 2596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(LoadStorePostIndexFixed | memop | ImmLS(offset)); 2597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This case is handled in the macro assembler. 2600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 2601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsImmLSUnscaled(int64_t offset) { 2607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return is_int9(offset); 2608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsImmLSScaled(int64_t offset, LSDataSize size) { 2612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool offset_is_size_multiple = (((offset >> size) << size) == offset); 2613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return offset_is_size_multiple && is_uint12(offset >> size); 2614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsImmLSPair(int64_t offset, LSDataSize size) { 2618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool offset_is_size_multiple = (((offset >> size) << size) == offset); 2619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return offset_is_size_multiple && is_int7(offset >> size); 2620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Assembler::IsImmLLiteral(int64_t offset) { 2624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int inst_size = static_cast<int>(kInstructionSizeLog2); 2625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool offset_is_inst_multiple = 2626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (((offset >> inst_size) << inst_size) == offset); 2627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return offset_is_inst_multiple && is_intn(offset, ImmLLiteral_width); 2628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Test if a given value can be encoded in the immediate field of a logical 2632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// instruction. 2633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// If it can be encoded, the function returns true, and values pointed to by n, 2634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// imm_s and imm_r are updated with immediates encoded in the format required 2635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// by the corresponding fields in the logical instruction. 2636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// If it can not be encoded, the function returns false, and the values pointed 2637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// to by n, imm_s and imm_r are undefined. 2638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsImmLogical(uint64_t value, 2639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned width, 2640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned* n, 2641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned* imm_s, 2642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned* imm_r) { 2643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((n != NULL) && (imm_s != NULL) && (imm_r != NULL)); 2644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((width == kWRegSizeInBits) || (width == kXRegSizeInBits)); 2645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool negate = false; 2647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Logical immediates are encoded using parameters n, imm_s and imm_r using 2649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the following table: 2650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 2651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // N imms immr size S R 2652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 1 ssssss rrrrrr 64 UInt(ssssss) UInt(rrrrrr) 2653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 0 0sssss xrrrrr 32 UInt(sssss) UInt(rrrrr) 2654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 0 10ssss xxrrrr 16 UInt(ssss) UInt(rrrr) 2655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 0 110sss xxxrrr 8 UInt(sss) UInt(rrr) 2656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 0 1110ss xxxxrr 4 UInt(ss) UInt(rr) 2657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 0 11110s xxxxxr 2 UInt(s) UInt(r) 2658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // (s bits must not be all set) 2659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 2660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // A pattern is constructed of size bits, where the least significant S+1 bits 2661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // are set. The pattern is rotated right by R, and repeated across a 32 or 2662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 64-bit value, depending on destination register width. 2663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 2664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Put another way: the basic format of a logical immediate is a single 2665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // contiguous stretch of 1 bits, repeated across the whole word at intervals 2666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // given by a power of 2. To identify them quickly, we first locate the 2667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // lowest stretch of 1 bits, then the next 1 bit above that; that combination 2668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // is different for every logical immediate, so it gives us all the 2669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // information we need to identify the only logical immediate that our input 2670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // could be, and then we simply check if that's the value we actually have. 2671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 2672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // (The rotation parameter does give the possibility of the stretch of 1 bits 2673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // going 'round the end' of the word. To deal with that, we observe that in 2674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // any situation where that happens the bitwise NOT of the value is also a 2675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // valid logical immediate. So we simply invert the input whenever its low bit 2676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // is set, and then we know that the rotated case can't arise.) 2677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (value & 1) { 2679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the low bit is 1, negate the value, and set a flag to remember that we 2680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // did (so that we can adjust the return values appropriately). 2681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch negate = true; 2682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value = ~value; 2683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (width == kWRegSizeInBits) { 2686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // To handle 32-bit logical immediates, the very easiest thing is to repeat 2687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the input value twice to make a 64-bit word. The correct encoding of that 2688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // as a logical immediate will also be the correct encoding of the 32-bit 2689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // value. 2690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The most-significant 32 bits may not be zero (ie. negate is true) so 2692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // shift the value left before duplicating it. 2693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value <<= kWRegSizeInBits; 2694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value |= value >> kWRegSizeInBits; 2695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The basic analysis idea: imagine our input word looks like this. 2698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 2699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 0011111000111110001111100011111000111110001111100011111000111110 2700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // c b a 2701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // |<--d-->| 2702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 2703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We find the lowest set bit (as an actual power-of-2 value, not its index) 2704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // and call it a. Then we add a to our original number, which wipes out the 2705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // bottommost stretch of set bits and replaces it with a 1 carried into the 2706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // next zero bit. Then we look for the new lowest set bit, which is in 2707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // position b, and subtract it, so now our number is just like the original 2708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // but with the lowest stretch of set bits completely gone. Now we find the 2709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // lowest set bit again, which is position c in the diagram above. Then we'll 2710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // measure the distance d between bit positions a and c (using CLZ), and that 2711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // tells us that the only valid logical immediate that could possibly be equal 2712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to this number is the one in which a stretch of bits running from a to just 2713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // below b is replicated every d bits. 2714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint64_t a = LargestPowerOf2Divisor(value); 2715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint64_t value_plus_a = value + a; 2716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint64_t b = LargestPowerOf2Divisor(value_plus_a); 2717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint64_t value_plus_a_minus_b = value_plus_a - b; 2718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint64_t c = LargestPowerOf2Divisor(value_plus_a_minus_b); 2719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int d, clz_a, out_n; 2721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint64_t mask; 2722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (c != 0) { 2724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The general case, in which there is more than one stretch of set bits. 2725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute the repeat distance d, and set up a bitmask covering the basic 2726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // unit of repetition (i.e. a word with the bottom d bits set). Also, in all 2727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // of these cases the N bit of the output will be zero. 2728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch clz_a = CountLeadingZeros(a, kXRegSizeInBits); 2729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int clz_c = CountLeadingZeros(c, kXRegSizeInBits); 2730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch d = clz_a - clz_c; 2731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mask = ((V8_UINT64_C(1) << d) - 1); 2732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch out_n = 0; 2733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Handle degenerate cases. 2735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 2736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If any of those 'find lowest set bit' operations didn't find a set bit at 2737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // all, then the word will have been zero thereafter, so in particular the 2738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // last lowest_set_bit operation will have returned zero. So we can test for 2739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // all the special case conditions in one go by seeing if c is zero. 2740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (a == 0) { 2741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The input was zero (or all 1 bits, which will come to here too after we 2742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // inverted it at the start of the function), for which we just return 2743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // false. 2744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 2745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Otherwise, if c was zero but a was not, then there's just one stretch 2747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // of set bits in our word, meaning that we have the trivial case of 2748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // d == 64 and only one 'repetition'. Set up all the same variables as in 2749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the general case above, and set the N bit in the output. 2750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch clz_a = CountLeadingZeros(a, kXRegSizeInBits); 2751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch d = 64; 2752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mask = ~V8_UINT64_C(0); 2753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch out_n = 1; 2754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the repeat period d is not a power of two, it can't be encoded. 2758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!IS_POWER_OF_TWO(d)) { 2759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 2760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (((b - a) & ~mask) != 0) { 2763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the bit stretch (b - a) does not fit within the mask derived from the 2764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // repeat period, then fail. 2765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 2766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The only possible option is b - a repeated every d bits. Now we're going to 2769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // actually construct the valid logical immediate derived from that 2770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // specification, and see if it equals our original input. 2771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 2772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // To repeat a value every d bits, we multiply it by a number of the form 2773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // (1 + 2^d + 2^(2d) + ...), i.e. 0x0001000100010001 or similar. These can 2774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // be derived using a table lookup on CLZ(d). 2775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const uint64_t multipliers[] = { 2776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 0x0000000000000001UL, 2777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 0x0000000100000001UL, 2778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 0x0001000100010001UL, 2779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 0x0101010101010101UL, 2780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 0x1111111111111111UL, 2781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 0x5555555555555555UL, 2782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 2783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int multiplier_idx = CountLeadingZeros(d, kXRegSizeInBits) - 57; 2784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Ensure that the index to the multipliers array is within bounds. 2785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((multiplier_idx >= 0) && 2786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (static_cast<size_t>(multiplier_idx) < arraysize(multipliers))); 2787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint64_t multiplier = multipliers[multiplier_idx]; 2788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint64_t candidate = (b - a) * multiplier; 2789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (value != candidate) { 2791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The candidate pattern doesn't match our input value, so fail. 2792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 2793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We have a match! This is a valid logical immediate, so now we have to 2796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // construct the bits and pieces of the instruction encoding that generates 2797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // it. 2798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Count the set bits in our basic stretch. The special case of clz(0) == -1 2800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // makes the answer come out right for stretches that reach the very top of 2801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the word (e.g. numbers like 0xffffc00000000000). 2802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int clz_b = (b == 0) ? -1 : CountLeadingZeros(b, kXRegSizeInBits); 2803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int s = clz_a - clz_b; 2804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Decide how many bits to rotate right by, to put the low bit of that basic 2806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // stretch in position a. 2807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int r; 2808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (negate) { 2809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If we inverted the input right at the start of this function, here's 2810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // where we compensate: the number of set bits becomes the number of clear 2811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // bits, and the rotation count is based on position b rather than position 2812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // a (since b is the location of the 'lowest' 1 bit after inversion). 2813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch s = d - s; 2814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch r = (clz_b + 1) & (d - 1); 2815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch r = (clz_a + 1) & (d - 1); 2817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Now we're done, except for having to encode the S output in such a way that 2820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // it gives both the number of set bits and the length of the repeated 2821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // segment. The s field is encoded like this: 2822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 2823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // imms size S 2824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // ssssss 64 UInt(ssssss) 2825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 0sssss 32 UInt(sssss) 2826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 10ssss 16 UInt(ssss) 2827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 110sss 8 UInt(sss) 2828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 1110ss 4 UInt(ss) 2829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 11110s 2 UInt(s) 2830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 2831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // So we 'or' (-d << 1) with our computed s to form imms. 2832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *n = out_n; 2833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *imm_s = ((-d << 1) | (s - 1)) & 0x3f; 2834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *imm_r = r; 2835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 2837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsImmConditionalCompare(int64_t immediate) { 2841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return is_uint5(immediate); 2842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsImmFP32(float imm) { 2846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Valid values will have the form: 2847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // aBbb.bbbc.defg.h000.0000.0000.0000.0000 2848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t bits = float_to_rawbits(imm); 2849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // bits[19..0] are cleared. 2850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((bits & 0x7ffff) != 0) { 2851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 2852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // bits[29..25] are all set or all cleared. 2855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t b_pattern = (bits >> 16) & 0x3e00; 2856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (b_pattern != 0 && b_pattern != 0x3e00) { 2857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 2858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // bit[30] and bit[29] are opposite. 2861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (((bits ^ (bits << 1)) & 0x40000000) == 0) { 2862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 2863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 2866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::IsImmFP64(double imm) { 2870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Valid values will have the form: 2871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // aBbb.bbbb.bbcd.efgh.0000.0000.0000.0000 2872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 0000.0000.0000.0000.0000.0000.0000.0000 2873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint64_t bits = double_to_rawbits(imm); 2874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // bits[47..0] are cleared. 2875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((bits & 0xffffffffffffL) != 0) { 2876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 2877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // bits[61..54] are all set or all cleared. 2880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t b_pattern = (bits >> 48) & 0x3fc0; 2881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (b_pattern != 0 && b_pattern != 0x3fc0) { 2882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 2883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // bit[62] and bit[61] are opposite. 2886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (((bits ^ (bits << 1)) & 0x4000000000000000L) == 0) { 2887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 2888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 2891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::GrowBuffer() { 2895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!own_buffer_) FATAL("external code buffer is too small"); 2896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute new buffer size. 2898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CodeDesc desc; // the new buffer 2899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (buffer_size_ < 1 * MB) { 2900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc.buffer_size = 2 * buffer_size_; 2901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc.buffer_size = buffer_size_ + 1 * MB; 2903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_GT(desc.buffer_size, 0); // No overflow. 2905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch byte* buffer = reinterpret_cast<byte*>(buffer_); 2907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set up new buffer. 2909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc.buffer = NewArray<byte>(desc.buffer_size); 2910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch desc.origin = this; 2911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc.instr_size = pc_offset(); 2913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch desc.reloc_size = 2914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static_cast<int>((buffer + buffer_size_) - reloc_info_writer.pos()); 2915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Copy the data. 2917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch intptr_t pc_delta = desc.buffer - buffer; 2918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch intptr_t rc_delta = (desc.buffer + desc.buffer_size) - 2919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (buffer + buffer_size_); 2920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch memmove(desc.buffer, buffer, desc.instr_size); 2921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch memmove(reloc_info_writer.pos() + rc_delta, 2922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reloc_info_writer.pos(), desc.reloc_size); 2923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Switch buffers. 2925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DeleteArray(buffer_); 2926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch buffer_ = desc.buffer; 2927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch buffer_size_ = desc.buffer_size; 2928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pc_ = reinterpret_cast<byte*>(pc_) + pc_delta; 2929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta, 2930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reloc_info_writer.last_pc() + pc_delta); 2931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // None of our relocation types are pc relative pointing outside the code 2933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // buffer nor pc absolute pointing inside the code buffer, so there is no need 2934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to relocate any emitted relocation entries. 2935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Relocate internal references. 2937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (auto pos : internal_reference_positions_) { 2938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch intptr_t* p = reinterpret_cast<intptr_t*>(buffer_ + pos); 2939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *p += pc_delta; 2940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Pending relocation entries are also relative, no need to relocate. 2943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { 2947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We do not try to reuse pool constants. 2948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RelocInfo rinfo(isolate(), reinterpret_cast<byte*>(pc_), rmode, data, NULL); 2949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (((rmode >= RelocInfo::COMMENT) && 29501b268ca467c924004286c97bac133db489cf43d0Ben Murdoch (rmode <= RelocInfo::DEBUG_BREAK_SLOT_AT_TAIL_CALL)) || 2951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (rmode == RelocInfo::INTERNAL_REFERENCE) || 2952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (rmode == RelocInfo::CONST_POOL) || (rmode == RelocInfo::VENEER_POOL) || 2953537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch (rmode == RelocInfo::DEOPT_REASON) || (rmode == RelocInfo::DEOPT_ID) || 2954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (rmode == RelocInfo::GENERATOR_CONTINUATION)) { 2955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Adjust code for new modes. 2956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(RelocInfo::IsDebugBreakSlot(rmode) || RelocInfo::IsComment(rmode) || 2957537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RelocInfo::IsDeoptReason(rmode) || RelocInfo::IsDeoptId(rmode) || 2958537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch RelocInfo::IsPosition(rmode) || 2959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RelocInfo::IsInternalReference(rmode) || 2960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RelocInfo::IsConstPool(rmode) || RelocInfo::IsVeneerPool(rmode) || 2961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RelocInfo::IsGeneratorContinuation(rmode)); 2962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // These modes do not need an entry in the constant pool. 2963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constpool_.RecordEntry(data, rmode); 2965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Make sure the constant pool is not emitted in place of the next 2966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // instruction for which we just recorded relocation info. 2967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BlockConstPoolFor(1); 2968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!RelocInfo::IsNone(rmode)) { 2971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Don't record external references unless the heap will be serialized. 2972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (rmode == RelocInfo::EXTERNAL_REFERENCE && 2973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !serializer_enabled() && !emit_debug_code()) { 2974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 2975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(buffer_space() >= kMaxRelocSize); // too late to grow buffer here 2977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (rmode == RelocInfo::CODE_TARGET_WITH_ID) { 2978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RelocInfo reloc_info_with_ast_id(isolate(), reinterpret_cast<byte*>(pc_), 2979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch rmode, RecordedAstId().ToInt(), NULL); 2980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClearRecordedAstId(); 2981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reloc_info_writer.Write(&reloc_info_with_ast_id); 2982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reloc_info_writer.Write(&rinfo); 2984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::BlockConstPoolFor(int instructions) { 2990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int pc_limit = pc_offset() + instructions * kInstructionSize; 2991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (no_const_pool_before_ < pc_limit) { 2992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch no_const_pool_before_ = pc_limit; 2993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Make sure the pool won't be blocked for too long. 2994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(pc_limit < constpool_.MaxPcOffset()); 2995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (next_constant_pool_check_ < no_const_pool_before_) { 2998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch next_constant_pool_check_ = no_const_pool_before_; 2999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::CheckConstPool(bool force_emit, bool require_jump) { 3004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Some short sequence of instruction mustn't be broken up by constant pool 3005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // emission, such sequences are protected by calls to BlockConstPoolFor and 3006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // BlockConstPoolScope. 3007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (is_const_pool_blocked()) { 3008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Something is wrong if emission is forced and blocked at the same time. 3009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!force_emit); 3010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 3011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // There is nothing to do if there are no pending constant pool entries. 3014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (constpool_.IsEmpty()) { 3015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Calculate the offset of the next check. 3016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetNextConstPoolCheckIn(kCheckConstPoolInterval); 3017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 3018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We emit a constant pool when: 3021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // * requested to do so by parameter force_emit (e.g. after each function). 3022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // * the distance to the first instruction accessing the constant pool is 3023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // kApproxMaxDistToConstPool or more. 3024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // * the number of entries in the pool is kApproxMaxPoolEntryCount or more. 3025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int dist = constpool_.DistanceToFirstUse(); 3026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int count = constpool_.EntryCount(); 3027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!force_emit && 3028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (dist < kApproxMaxDistToConstPool) && 3029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (count < kApproxMaxPoolEntryCount)) { 3030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 3031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Emit veneers for branches that would go out of range during emission of the 3035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // constant pool. 3036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int worst_case_size = constpool_.WorstCaseSize(); 3037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CheckVeneerPool(false, require_jump, 3038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kVeneerDistanceMargin + worst_case_size); 3039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check that the code buffer is large enough before emitting the constant 3041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // pool (this includes the gap to the relocation information). 3042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int needed_space = worst_case_size + kGap + 1 * kInstructionSize; 3043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (buffer_space() <= needed_space) { 3044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GrowBuffer(); 3045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label size_check; 3048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&size_check); 3049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch constpool_.Emit(require_jump); 3050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SizeOfCodeGeneratedSince(&size_check) <= 3051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<unsigned>(worst_case_size)); 3052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Since a constant pool was just emitted, move the check offset forward by 3054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the standard interval. 3055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetNextConstPoolCheckIn(kCheckConstPoolInterval); 3056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Assembler::ShouldEmitVeneer(int max_reachable_pc, int margin) { 3060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Account for the branch around the veneers and the guard. 3061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int protection_offset = 2 * kInstructionSize; 3062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return pc_offset() > max_reachable_pc - margin - protection_offset - 3063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>(unresolved_branches_.size() * kMaxVeneerCodeSize); 3064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::RecordVeneerPool(int location_offset, int size) { 3068014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RelocInfo rinfo(isolate(), buffer_ + location_offset, RelocInfo::VENEER_POOL, 3069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static_cast<intptr_t>(size), NULL); 3070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reloc_info_writer.Write(&rinfo); 3071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::EmitVeneers(bool force_emit, bool need_protection, int margin) { 3075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BlockPoolsScope scope(this); 3076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RecordComment("[ Veneers"); 3077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The exact size of the veneer pool must be recorded (see the comment at the 3079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // declaration site of RecordConstPool()), but computing the number of 3080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // veneers that will be generated is not obvious. So instead we remember the 3081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // current position and will record the size after the pool has been 3082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // generated. 3083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label size_check; 3084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&size_check); 3085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int veneer_pool_relocinfo_loc = pc_offset(); 3086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label end; 3088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (need_protection) { 3089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch b(&end); 3090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EmitVeneersGuard(); 3093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label veneer_size_check; 3095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch std::multimap<int, FarBranchInfo>::iterator it, it_to_delete; 3097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch it = unresolved_branches_.begin(); 3099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (it != unresolved_branches_.end()) { 3100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (force_emit || ShouldEmitVeneer(it->first, margin)) { 3101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instruction* branch = InstructionAt(it->second.pc_offset_); 3102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* label = it->second.label_; 3103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 3105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&veneer_size_check); 3106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 3107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Patch the branch to point to the current position, and emit a branch 3108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to the label. 3109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instruction* veneer = reinterpret_cast<Instruction*>(pc_); 3110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RemoveBranchFromLabelLinkChain(branch, label, veneer); 3111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch branch->SetImmPCOffsetTarget(isolate(), veneer); 3112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch b(label); 3113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 3114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SizeOfCodeGeneratedSince(&veneer_size_check) <= 3115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<uint64_t>(kMaxVeneerCodeSize)); 3116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch veneer_size_check.Unuse(); 3117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 3118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch it_to_delete = it++; 3120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unresolved_branches_.erase(it_to_delete); 3121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ++it; 3123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Record the veneer pool size. 3127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int pool_size = static_cast<int>(SizeOfCodeGeneratedSince(&size_check)); 3128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RecordVeneerPool(veneer_pool_relocinfo_loc, pool_size); 3129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (unresolved_branches_.empty()) { 3131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch next_veneer_pool_check_ = kMaxInt; 3132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch next_veneer_pool_check_ = 3134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unresolved_branches_first_limit() - kVeneerDistanceCheckMargin; 3135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&end); 3138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RecordComment("]"); 3140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::CheckVeneerPool(bool force_emit, bool require_jump, 3144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int margin) { 3145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // There is nothing to do if there are no pending veneer pool entries. 3146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (unresolved_branches_.empty()) { 3147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(next_veneer_pool_check_ == kMaxInt); 3148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 3149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(pc_offset() < unresolved_branches_first_limit()); 3152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Some short sequence of instruction mustn't be broken up by veneer pool 3154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // emission, such sequences are protected by calls to BlockVeneerPoolFor and 3155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // BlockVeneerPoolScope. 3156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (is_veneer_pool_blocked()) { 3157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!force_emit); 3158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 3159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!require_jump) { 3162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Prefer emitting veneers protected by an existing instruction. 3163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch margin *= kVeneerNoProtectionFactor; 3164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (force_emit || ShouldEmitVeneers(margin)) { 3166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EmitVeneers(force_emit, require_jump, margin); 3167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch next_veneer_pool_check_ = 3169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unresolved_branches_first_limit() - kVeneerDistanceCheckMargin; 3170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint Assembler::buffer_space() const { 3175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return static_cast<int>(reloc_info_writer.pos() - 3176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch reinterpret_cast<byte*>(pc_)); 3177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::RecordConstPool(int size) { 3181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We only need this for debugger support, to correctly compute offsets in the 3182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // code. 3183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RecordRelocInfo(RelocInfo::CONST_POOL, static_cast<intptr_t>(size)); 3184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid PatchingAssembler::PatchAdrFar(int64_t target_offset) { 3188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The code at the current instruction should be: 3189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // adr rd, 0 3190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // nop (adr_far) 3191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // nop (adr_far) 3192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // movz scratch, 0 3193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Verify the expected code. 3195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instruction* expected_adr = InstructionAt(0); 3196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(expected_adr->IsAdr() && (expected_adr->ImmPCRel() == 0)); 3197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int rd_code = expected_adr->Rd(); 3198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < kAdrFarPatchableNNops; ++i) { 3199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(InstructionAt((i + 1) * kInstructionSize)->IsNop(ADR_FAR_NOP)); 3200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instruction* expected_movz = 3202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionAt((kAdrFarPatchableNInstrs - 1) * kInstructionSize); 3203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(expected_movz->IsMovz() && 3204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (expected_movz->ImmMoveWide() == 0) && 3205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (expected_movz->ShiftMoveWide() == 0)); 3206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int scratch_code = expected_movz->Rd(); 3207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Patch to load the correct address. 3209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register rd = Register::XRegFromCode(rd_code); 3210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch = Register::XRegFromCode(scratch_code); 3211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Addresses are only 48 bits. 3212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch adr(rd, target_offset & 0xFFFF); 3213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movz(scratch, (target_offset >> 16) & 0xFFFF, 16); 3214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movk(scratch, (target_offset >> 32) & 0xFFFF, 32); 3215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((target_offset >> 48) == 0); 3216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch add(rd, rd, scratch); 3217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 3221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 3222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif // V8_TARGET_ARCH_ARM64 3224