1b8021494Sopenharmony_ci// Copyright 2017, VIXL authors 2b8021494Sopenharmony_ci// All rights reserved. 3b8021494Sopenharmony_ci// 4b8021494Sopenharmony_ci// Redistribution and use in source and binary forms, with or without 5b8021494Sopenharmony_ci// modification, are permitted provided that the following conditions are met: 6b8021494Sopenharmony_ci// 7b8021494Sopenharmony_ci// * Redistributions of source code must retain the above copyright notice, 8b8021494Sopenharmony_ci// this list of conditions and the following disclaimer. 9b8021494Sopenharmony_ci// * Redistributions in binary form must reproduce the above copyright notice, 10b8021494Sopenharmony_ci// this list of conditions and the following disclaimer in the documentation 11b8021494Sopenharmony_ci// and/or other materials provided with the distribution. 12b8021494Sopenharmony_ci// * Neither the name of ARM Limited nor the names of its contributors may be 13b8021494Sopenharmony_ci// used to endorse or promote products derived from this software without 14b8021494Sopenharmony_ci// specific prior written permission. 15b8021494Sopenharmony_ci// 16b8021494Sopenharmony_ci// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND 17b8021494Sopenharmony_ci// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18b8021494Sopenharmony_ci// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19b8021494Sopenharmony_ci// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 20b8021494Sopenharmony_ci// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21b8021494Sopenharmony_ci// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22b8021494Sopenharmony_ci// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23b8021494Sopenharmony_ci// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24b8021494Sopenharmony_ci// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25b8021494Sopenharmony_ci// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26b8021494Sopenharmony_ci 27b8021494Sopenharmony_ci#ifndef VIXL_AARCH32_LABEL_AARCH32_H_ 28b8021494Sopenharmony_ci#define VIXL_AARCH32_LABEL_AARCH32_H_ 29b8021494Sopenharmony_ci 30b8021494Sopenharmony_ciextern "C" { 31b8021494Sopenharmony_ci#include <stdint.h> 32b8021494Sopenharmony_ci} 33b8021494Sopenharmony_ci 34b8021494Sopenharmony_ci#include <algorithm> 35b8021494Sopenharmony_ci#include <cstddef> 36b8021494Sopenharmony_ci#include <iomanip> 37b8021494Sopenharmony_ci#include <list> 38b8021494Sopenharmony_ci 39b8021494Sopenharmony_ci#include "invalset-vixl.h" 40b8021494Sopenharmony_ci#include "pool-manager.h" 41b8021494Sopenharmony_ci#include "utils-vixl.h" 42b8021494Sopenharmony_ci 43b8021494Sopenharmony_ci#include "constants-aarch32.h" 44b8021494Sopenharmony_ci#include "instructions-aarch32.h" 45b8021494Sopenharmony_ci 46b8021494Sopenharmony_cinamespace vixl { 47b8021494Sopenharmony_ci 48b8021494Sopenharmony_cinamespace aarch32 { 49b8021494Sopenharmony_ci 50b8021494Sopenharmony_ciclass MacroAssembler; 51b8021494Sopenharmony_ci 52b8021494Sopenharmony_ciclass Location : public LocationBase<int32_t> { 53b8021494Sopenharmony_ci friend class Assembler; 54b8021494Sopenharmony_ci friend class MacroAssembler; 55b8021494Sopenharmony_ci 56b8021494Sopenharmony_ci public: 57b8021494Sopenharmony_ci // Unbound location that can be used with the assembler bind() method and 58b8021494Sopenharmony_ci // with the assembler methods for generating instructions, but will never 59b8021494Sopenharmony_ci // be handled by the pool manager. 60b8021494Sopenharmony_ci#ifndef PANDA_BUILD 61b8021494Sopenharmony_ci Location() 62b8021494Sopenharmony_ci : LocationBase<int32_t>(kRawLocation, 1 /* placeholder size*/), 63b8021494Sopenharmony_ci referenced_(false) {} 64b8021494Sopenharmony_ci#else 65b8021494Sopenharmony_ci Location() = delete; 66b8021494Sopenharmony_ci Location(AllocatorWrapper allocator) 67b8021494Sopenharmony_ci : LocationBase<int32_t>(kRawLocation, 1 /* dummy size*/), 68b8021494Sopenharmony_ci referenced_(false), 69b8021494Sopenharmony_ci forward_(allocator) {} 70b8021494Sopenharmony_ci#endif 71b8021494Sopenharmony_ci 72b8021494Sopenharmony_ci typedef int32_t Offset; 73b8021494Sopenharmony_ci 74b8021494Sopenharmony_ci ~Location() VIXL_NEGATIVE_TESTING_ALLOW_EXCEPTION { 75b8021494Sopenharmony_ci // Codegen may create empty labels 76b8021494Sopenharmony_ci#if defined(VIXL_DEBUG) && !defined(PANDA_BUILD) 77b8021494Sopenharmony_ci if (IsReferenced() && !IsBound()) { 78b8021494Sopenharmony_ci VIXL_ABORT_WITH_MSG("Location, label or literal used but not bound.\n"); 79b8021494Sopenharmony_ci } 80b8021494Sopenharmony_ci#endif 81b8021494Sopenharmony_ci } 82b8021494Sopenharmony_ci 83b8021494Sopenharmony_ci bool IsReferenced() const { return referenced_; } 84b8021494Sopenharmony_ci 85b8021494Sopenharmony_ci private: 86b8021494Sopenharmony_ci class EmitOperator { 87b8021494Sopenharmony_ci public: 88b8021494Sopenharmony_ci explicit EmitOperator(InstructionSet isa) : isa_(isa) { 89b8021494Sopenharmony_ci#if defined(VIXL_INCLUDE_TARGET_A32_ONLY) 90b8021494Sopenharmony_ci USE(isa_); 91b8021494Sopenharmony_ci VIXL_ASSERT(isa == A32); 92b8021494Sopenharmony_ci#elif defined(VIXL_INCLUDE_TARGET_T32_ONLY) 93b8021494Sopenharmony_ci USE(isa_); 94b8021494Sopenharmony_ci VIXL_ASSERT(isa == T32); 95b8021494Sopenharmony_ci#endif 96b8021494Sopenharmony_ci } 97b8021494Sopenharmony_ci virtual ~EmitOperator() {} 98b8021494Sopenharmony_ci virtual uint32_t Encode(uint32_t /*instr*/, 99b8021494Sopenharmony_ci Location::Offset /*pc*/, 100b8021494Sopenharmony_ci const Location* /*label*/) const { 101b8021494Sopenharmony_ci return 0; 102b8021494Sopenharmony_ci } 103b8021494Sopenharmony_ci#if defined(VIXL_INCLUDE_TARGET_A32_ONLY) 104b8021494Sopenharmony_ci bool IsUsingT32() const { return false; } 105b8021494Sopenharmony_ci#elif defined(VIXL_INCLUDE_TARGET_T32_ONLY) 106b8021494Sopenharmony_ci bool IsUsingT32() const { return true; } 107b8021494Sopenharmony_ci#else 108b8021494Sopenharmony_ci bool IsUsingT32() const { return isa_ == T32; } 109b8021494Sopenharmony_ci#endif 110b8021494Sopenharmony_ci 111b8021494Sopenharmony_ci private: 112b8021494Sopenharmony_ci InstructionSet isa_; 113b8021494Sopenharmony_ci }; 114b8021494Sopenharmony_ci 115b8021494Sopenharmony_ci protected: 116b8021494Sopenharmony_ci class ForwardRef : public ForwardReference<int32_t> { 117b8021494Sopenharmony_ci public: 118b8021494Sopenharmony_ci // Default constructor for InvalSet. 119b8021494Sopenharmony_ci ForwardRef() : ForwardReference<int32_t>(0, 0, 0, 0, 1), op_(NULL) {} 120b8021494Sopenharmony_ci 121b8021494Sopenharmony_ci ForwardRef(const Location::EmitOperator* op, 122b8021494Sopenharmony_ci int32_t location, 123b8021494Sopenharmony_ci int size, 124b8021494Sopenharmony_ci int32_t min_object_location, 125b8021494Sopenharmony_ci int32_t max_object_location, 126b8021494Sopenharmony_ci int object_alignment = 1) 127b8021494Sopenharmony_ci : ForwardReference<int32_t>(location, 128b8021494Sopenharmony_ci size, 129b8021494Sopenharmony_ci min_object_location, 130b8021494Sopenharmony_ci max_object_location, 131b8021494Sopenharmony_ci object_alignment), 132b8021494Sopenharmony_ci op_(op) {} 133b8021494Sopenharmony_ci 134b8021494Sopenharmony_ci const Location::EmitOperator* op() const { return op_; } 135b8021494Sopenharmony_ci 136b8021494Sopenharmony_ci // We must provide comparison operators to work with InvalSet. 137b8021494Sopenharmony_ci bool operator==(const ForwardRef& other) const { 138b8021494Sopenharmony_ci return GetLocation() == other.GetLocation(); 139b8021494Sopenharmony_ci } 140b8021494Sopenharmony_ci bool operator<(const ForwardRef& other) const { 141b8021494Sopenharmony_ci return GetLocation() < other.GetLocation(); 142b8021494Sopenharmony_ci } 143b8021494Sopenharmony_ci bool operator<=(const ForwardRef& other) const { 144b8021494Sopenharmony_ci return GetLocation() <= other.GetLocation(); 145b8021494Sopenharmony_ci } 146b8021494Sopenharmony_ci bool operator>(const ForwardRef& other) const { 147b8021494Sopenharmony_ci return GetLocation() > other.GetLocation(); 148b8021494Sopenharmony_ci } 149b8021494Sopenharmony_ci 150b8021494Sopenharmony_ci private: 151b8021494Sopenharmony_ci const Location::EmitOperator* op_; 152b8021494Sopenharmony_ci }; 153b8021494Sopenharmony_ci 154b8021494Sopenharmony_ci static const int kNPreallocatedElements = 4; 155b8021494Sopenharmony_ci // The following parameters will not affect ForwardRefList in practice, as we 156b8021494Sopenharmony_ci // resolve all references at once and clear the list, so we do not need to 157b8021494Sopenharmony_ci // remove individual elements by invalidating them. 158b8021494Sopenharmony_ci static const int32_t kInvalidLinkKey = INT32_MAX; 159b8021494Sopenharmony_ci static const size_t kReclaimFrom = 512; 160b8021494Sopenharmony_ci static const size_t kReclaimFactor = 2; 161b8021494Sopenharmony_ci 162b8021494Sopenharmony_ci typedef InvalSet<ForwardRef, 163b8021494Sopenharmony_ci kNPreallocatedElements, 164b8021494Sopenharmony_ci int32_t, 165b8021494Sopenharmony_ci kInvalidLinkKey, 166b8021494Sopenharmony_ci kReclaimFrom, 167b8021494Sopenharmony_ci kReclaimFactor> 168b8021494Sopenharmony_ci ForwardRefListBase; 169b8021494Sopenharmony_ci typedef InvalSetIterator<ForwardRefListBase> ForwardRefListIteratorBase; 170b8021494Sopenharmony_ci 171b8021494Sopenharmony_ci class ForwardRefList : public ForwardRefListBase { 172b8021494Sopenharmony_ci public: 173b8021494Sopenharmony_ci#ifndef PANDA_BUILD 174b8021494Sopenharmony_ci ForwardRefList() : ForwardRefListBase() {} 175b8021494Sopenharmony_ci#else 176b8021494Sopenharmony_ci ForwardRefList() = delete; 177b8021494Sopenharmony_ci ForwardRefList(AllocatorWrapper allocator) : ForwardRefListBase(allocator) {} 178b8021494Sopenharmony_ci#endif 179b8021494Sopenharmony_ci using ForwardRefListBase::Back; 180b8021494Sopenharmony_ci using ForwardRefListBase::Front; 181b8021494Sopenharmony_ci }; 182b8021494Sopenharmony_ci 183b8021494Sopenharmony_ci class ForwardRefListIterator : public ForwardRefListIteratorBase { 184b8021494Sopenharmony_ci public: 185b8021494Sopenharmony_ci explicit ForwardRefListIterator(Location* location) 186b8021494Sopenharmony_ci : ForwardRefListIteratorBase(&location->forward_) {} 187b8021494Sopenharmony_ci 188b8021494Sopenharmony_ci // TODO: Remove these and use the STL-like interface instead. We'll need a 189b8021494Sopenharmony_ci // const_iterator implemented for this. 190b8021494Sopenharmony_ci using ForwardRefListIteratorBase::Advance; 191b8021494Sopenharmony_ci using ForwardRefListIteratorBase::Current; 192b8021494Sopenharmony_ci }; 193b8021494Sopenharmony_ci 194b8021494Sopenharmony_ci // For InvalSet::GetKey() and InvalSet::SetKey(). 195b8021494Sopenharmony_ci friend class InvalSet<ForwardRef, 196b8021494Sopenharmony_ci kNPreallocatedElements, 197b8021494Sopenharmony_ci int32_t, 198b8021494Sopenharmony_ci kInvalidLinkKey, 199b8021494Sopenharmony_ci kReclaimFrom, 200b8021494Sopenharmony_ci kReclaimFactor>; 201b8021494Sopenharmony_ci 202b8021494Sopenharmony_ci private: 203b8021494Sopenharmony_ci virtual void ResolveReferences(internal::AssemblerBase* assembler) 204b8021494Sopenharmony_ci VIXL_OVERRIDE; 205b8021494Sopenharmony_ci 206b8021494Sopenharmony_ci void SetReferenced() { referenced_ = true; } 207b8021494Sopenharmony_ci 208b8021494Sopenharmony_ci bool HasForwardReferences() const { return !forward_.empty(); } 209b8021494Sopenharmony_ci 210b8021494Sopenharmony_ci ForwardRef GetLastForwardReference() const { 211b8021494Sopenharmony_ci VIXL_ASSERT(HasForwardReferences()); 212b8021494Sopenharmony_ci return forward_.Back(); 213b8021494Sopenharmony_ci } 214b8021494Sopenharmony_ci 215b8021494Sopenharmony_ci // Add forward reference to this object. Called from the assembler. 216b8021494Sopenharmony_ci void AddForwardRef(int32_t instr_location, 217b8021494Sopenharmony_ci const EmitOperator& op, 218b8021494Sopenharmony_ci const ReferenceInfo* info); 219b8021494Sopenharmony_ci 220b8021494Sopenharmony_ci // Check if we need to add padding when binding this object, in order to 221b8021494Sopenharmony_ci // meet the minimum location requirement. 222b8021494Sopenharmony_ci bool Needs16BitPadding(int location) const; 223b8021494Sopenharmony_ci 224b8021494Sopenharmony_ci void EncodeLocationFor(internal::AssemblerBase* assembler, 225b8021494Sopenharmony_ci int32_t from, 226b8021494Sopenharmony_ci const Location::EmitOperator* encoder); 227b8021494Sopenharmony_ci 228b8021494Sopenharmony_ci // True if the label has been used at least once. 229b8021494Sopenharmony_ci bool referenced_; 230b8021494Sopenharmony_ci 231b8021494Sopenharmony_ci protected: 232b8021494Sopenharmony_ci // Types passed to LocationBase. Must be distinct for unbound Locations (not 233b8021494Sopenharmony_ci // relevant for bound locations, as they don't have a corresponding 234b8021494Sopenharmony_ci // PoolObject). 235b8021494Sopenharmony_ci static const int kRawLocation = 0; // Will not be used by the pool manager. 236b8021494Sopenharmony_ci static const int kVeneerType = 1; 237b8021494Sopenharmony_ci static const int kLiteralType = 2; 238b8021494Sopenharmony_ci 239b8021494Sopenharmony_ci // Contains the references to the unbound label 240b8021494Sopenharmony_ci ForwardRefList forward_; 241b8021494Sopenharmony_ci 242b8021494Sopenharmony_ci#ifndef PANDA_BUILD 243b8021494Sopenharmony_ci // To be used only by derived classes. 244b8021494Sopenharmony_ci Location(uint32_t type, int size, int alignment) 245b8021494Sopenharmony_ci : LocationBase<int32_t>(type, size, alignment), referenced_(false) {} 246b8021494Sopenharmony_ci#else 247b8021494Sopenharmony_ci Location(AllocatorWrapper allocator, uint32_t type, int size, int alignment) 248b8021494Sopenharmony_ci : LocationBase<int32_t>(type, size, alignment), referenced_(false), forward_(allocator){} 249b8021494Sopenharmony_ci#endif 250b8021494Sopenharmony_ci 251b8021494Sopenharmony_ci#ifndef PANDA_BUILD 252b8021494Sopenharmony_ci // To be used only by derived classes. 253b8021494Sopenharmony_ci explicit Location(Offset location) 254b8021494Sopenharmony_ci : LocationBase<int32_t>(location), referenced_(false) {} 255b8021494Sopenharmony_ci#else 256b8021494Sopenharmony_ci explicit Location(Offset location) = delete; 257b8021494Sopenharmony_ci Location(AllocatorWrapper allocator, Offset location) 258b8021494Sopenharmony_ci : LocationBase<int32_t>(location), referenced_(false), forward_(allocator) {} 259b8021494Sopenharmony_ci#endif 260b8021494Sopenharmony_ci 261b8021494Sopenharmony_ci virtual int GetMaxAlignment() const VIXL_OVERRIDE; 262b8021494Sopenharmony_ci virtual int GetMinLocation() const VIXL_OVERRIDE; 263b8021494Sopenharmony_ci 264b8021494Sopenharmony_ci private: 265b8021494Sopenharmony_ci // Included to make the class concrete, however should never be called. 266b8021494Sopenharmony_ci virtual void EmitPoolObject(MacroAssemblerInterface* masm) VIXL_OVERRIDE { 267b8021494Sopenharmony_ci USE(masm); 268b8021494Sopenharmony_ci VIXL_UNREACHABLE(); 269b8021494Sopenharmony_ci } 270b8021494Sopenharmony_ci}; 271b8021494Sopenharmony_ci 272b8021494Sopenharmony_ciclass Label : public Location { 273b8021494Sopenharmony_ci static const int kVeneerSize = 4; 274b8021494Sopenharmony_ci // Use an alignment of 1 for all architectures. Even though we can bind an 275b8021494Sopenharmony_ci // unused label, because of the way the MacroAssembler works we can always be 276b8021494Sopenharmony_ci // sure to have the correct buffer alignment for the instruction set we are 277b8021494Sopenharmony_ci // using, so we do not need to enforce additional alignment requirements 278b8021494Sopenharmony_ci // here. 279b8021494Sopenharmony_ci // TODO: Consider modifying the interface of the pool manager to pass an 280b8021494Sopenharmony_ci // optional additional alignment to Bind() in order to handle cases where the 281b8021494Sopenharmony_ci // buffer could be unaligned. 282b8021494Sopenharmony_ci static const int kVeneerAlignment = 1; 283b8021494Sopenharmony_ci 284b8021494Sopenharmony_ci public: 285b8021494Sopenharmony_ci#ifndef PANDA_BUILD 286b8021494Sopenharmony_ci Label() : Location(kVeneerType, kVeneerSize, kVeneerAlignment) {} 287b8021494Sopenharmony_ci explicit Label(Offset location) : Location(location) {} 288b8021494Sopenharmony_ci#else 289b8021494Sopenharmony_ci Label() = delete; 290b8021494Sopenharmony_ci Label(AllocatorWrapper allocator) : Location(allocator, kVeneerType, kVeneerSize, kVeneerAlignment) {} 291b8021494Sopenharmony_ci explicit Label(Offset location) = delete; 292b8021494Sopenharmony_ci explicit Label(AllocatorWrapper allocator, Offset location) : Location(allocator, location) {} 293b8021494Sopenharmony_ci#endif 294b8021494Sopenharmony_ci 295b8021494Sopenharmony_ci private: 296b8021494Sopenharmony_ci virtual bool ShouldBeDeletedOnPlacementByPoolManager() const VIXL_OVERRIDE { 297b8021494Sopenharmony_ci return false; 298b8021494Sopenharmony_ci } 299b8021494Sopenharmony_ci virtual bool ShouldDeletePoolObjectOnPlacement() const VIXL_OVERRIDE { 300b8021494Sopenharmony_ci return false; 301b8021494Sopenharmony_ci } 302b8021494Sopenharmony_ci 303b8021494Sopenharmony_ci virtual void UpdatePoolObject(PoolObject<int32_t>* object) VIXL_OVERRIDE; 304b8021494Sopenharmony_ci virtual void EmitPoolObject(MacroAssemblerInterface* masm) VIXL_OVERRIDE; 305b8021494Sopenharmony_ci 306b8021494Sopenharmony_ci virtual bool UsePoolObjectEmissionMargin() const VIXL_OVERRIDE { 307b8021494Sopenharmony_ci return true; 308b8021494Sopenharmony_ci } 309b8021494Sopenharmony_ci virtual int32_t GetPoolObjectEmissionMargin() const VIXL_OVERRIDE { 310b8021494Sopenharmony_ci VIXL_ASSERT(UsePoolObjectEmissionMargin() == true); 311b8021494Sopenharmony_ci return 1 * KBytes; 312b8021494Sopenharmony_ci } 313b8021494Sopenharmony_ci}; 314b8021494Sopenharmony_ci 315b8021494Sopenharmony_ciclass RawLiteral : public Location { 316b8021494Sopenharmony_ci // Some load instructions require alignment to 4 bytes. Since we do 317b8021494Sopenharmony_ci // not know what instructions will reference a literal after we place 318b8021494Sopenharmony_ci // it, we enforce a 4 byte alignment for literals that are 4 bytes or 319b8021494Sopenharmony_ci // larger. 320b8021494Sopenharmony_ci static const int kLiteralAlignment = 4; 321b8021494Sopenharmony_ci 322b8021494Sopenharmony_ci public: 323b8021494Sopenharmony_ci enum PlacementPolicy { kPlacedWhenUsed, kManuallyPlaced }; 324b8021494Sopenharmony_ci 325b8021494Sopenharmony_ci enum DeletionPolicy { 326b8021494Sopenharmony_ci kDeletedOnPlacementByPool, 327b8021494Sopenharmony_ci kDeletedOnPoolDestruction, 328b8021494Sopenharmony_ci kManuallyDeleted 329b8021494Sopenharmony_ci }; 330b8021494Sopenharmony_ci 331b8021494Sopenharmony_ci#ifndef PANDA_BUILD 332b8021494Sopenharmony_ci RawLiteral(const void* addr, 333b8021494Sopenharmony_ci int size, 334b8021494Sopenharmony_ci PlacementPolicy placement_policy = kPlacedWhenUsed, 335b8021494Sopenharmony_ci DeletionPolicy deletion_policy = kManuallyDeleted) 336b8021494Sopenharmony_ci : Location(kLiteralType, 337b8021494Sopenharmony_ci size, 338b8021494Sopenharmony_ci (size < kLiteralAlignment) ? size : kLiteralAlignment), 339b8021494Sopenharmony_ci addr_(addr), 340b8021494Sopenharmony_ci manually_placed_(placement_policy == kManuallyPlaced), 341b8021494Sopenharmony_ci deletion_policy_(deletion_policy) { 342b8021494Sopenharmony_ci // We can't have manually placed literals that are not manually deleted. 343b8021494Sopenharmony_ci VIXL_ASSERT(!IsManuallyPlaced() || 344b8021494Sopenharmony_ci (GetDeletionPolicy() == kManuallyDeleted)); 345b8021494Sopenharmony_ci } 346b8021494Sopenharmony_ci RawLiteral(const void* addr, int size, DeletionPolicy deletion_policy) 347b8021494Sopenharmony_ci : Location(kLiteralType, 348b8021494Sopenharmony_ci size, 349b8021494Sopenharmony_ci (size < kLiteralAlignment) ? size : kLiteralAlignment), 350b8021494Sopenharmony_ci addr_(addr), 351b8021494Sopenharmony_ci manually_placed_(false), 352b8021494Sopenharmony_ci deletion_policy_(deletion_policy) {} 353b8021494Sopenharmony_ci#else 354b8021494Sopenharmony_ciRawLiteral(const void* addr, 355b8021494Sopenharmony_ci int size, 356b8021494Sopenharmony_ci PlacementPolicy placement_policy = kPlacedWhenUsed, 357b8021494Sopenharmony_ci DeletionPolicy deletion_policy = kManuallyDeleted) = delete; 358b8021494Sopenharmony_ciRawLiteral(AllocatorWrapper allocator, const void* addr, 359b8021494Sopenharmony_ci int size, 360b8021494Sopenharmony_ci PlacementPolicy placement_policy = kPlacedWhenUsed, 361b8021494Sopenharmony_ci DeletionPolicy deletion_policy = kManuallyDeleted) 362b8021494Sopenharmony_ci : Location(allocator, kLiteralType, 363b8021494Sopenharmony_ci size, 364b8021494Sopenharmony_ci (size < kLiteralAlignment) ? size : kLiteralAlignment), 365b8021494Sopenharmony_ci addr_(addr), 366b8021494Sopenharmony_ci manually_placed_(placement_policy == kManuallyPlaced), 367b8021494Sopenharmony_ci deletion_policy_(deletion_policy) { 368b8021494Sopenharmony_ci // We can't have manually placed literals that are not manually deleted. 369b8021494Sopenharmony_ci VIXL_ASSERT(!IsManuallyPlaced() || 370b8021494Sopenharmony_ci (GetDeletionPolicy() == kManuallyDeleted)); 371b8021494Sopenharmony_ci} 372b8021494Sopenharmony_ciRawLiteral(const void* addr, int size, DeletionPolicy deletion_policy) = delete; 373b8021494Sopenharmony_ci 374b8021494Sopenharmony_ciRawLiteral(AllocatorWrapper allocator, const void* addr, int size, DeletionPolicy deletion_policy) 375b8021494Sopenharmony_ci : Location(allocator, kLiteralType, 376b8021494Sopenharmony_ci size, 377b8021494Sopenharmony_ci (size < kLiteralAlignment) ? size : kLiteralAlignment), 378b8021494Sopenharmony_ci addr_(addr), 379b8021494Sopenharmony_ci manually_placed_(false), 380b8021494Sopenharmony_ci deletion_policy_(deletion_policy) {} 381b8021494Sopenharmony_ci 382b8021494Sopenharmony_ci#endif 383b8021494Sopenharmony_ci const void* GetDataAddress() const { return addr_; } 384b8021494Sopenharmony_ci int GetSize() const { return GetPoolObjectSizeInBytes(); } 385b8021494Sopenharmony_ci 386b8021494Sopenharmony_ci bool IsManuallyPlaced() const { return manually_placed_; } 387b8021494Sopenharmony_ci 388b8021494Sopenharmony_ci private: 389b8021494Sopenharmony_ci DeletionPolicy GetDeletionPolicy() const { return deletion_policy_; } 390b8021494Sopenharmony_ci 391b8021494Sopenharmony_ci virtual bool ShouldBeDeletedOnPlacementByPoolManager() const VIXL_OVERRIDE { 392b8021494Sopenharmony_ci return GetDeletionPolicy() == kDeletedOnPlacementByPool; 393b8021494Sopenharmony_ci } 394b8021494Sopenharmony_ci virtual bool ShouldBeDeletedOnPoolManagerDestruction() const VIXL_OVERRIDE { 395b8021494Sopenharmony_ci return GetDeletionPolicy() == kDeletedOnPoolDestruction; 396b8021494Sopenharmony_ci } 397b8021494Sopenharmony_ci virtual void EmitPoolObject(MacroAssemblerInterface* masm) VIXL_OVERRIDE; 398b8021494Sopenharmony_ci 399b8021494Sopenharmony_ci // Data address before it's moved into the code buffer. 400b8021494Sopenharmony_ci const void* const addr_; 401b8021494Sopenharmony_ci // When this flag is true, the label will be placed manually. 402b8021494Sopenharmony_ci bool manually_placed_; 403b8021494Sopenharmony_ci // When is the literal to be removed from the memory 404b8021494Sopenharmony_ci // Can be delete'd when: 405b8021494Sopenharmony_ci // moved into the code buffer: kDeletedOnPlacementByPool 406b8021494Sopenharmony_ci // the pool is delete'd: kDeletedOnPoolDestruction 407b8021494Sopenharmony_ci // or left to the application: kManuallyDeleted. 408b8021494Sopenharmony_ci DeletionPolicy deletion_policy_; 409b8021494Sopenharmony_ci 410b8021494Sopenharmony_ci friend class MacroAssembler; 411b8021494Sopenharmony_ci}; 412b8021494Sopenharmony_ci 413b8021494Sopenharmony_citemplate <typename T> 414b8021494Sopenharmony_ciclass Literal : public RawLiteral { 415b8021494Sopenharmony_ci public: 416b8021494Sopenharmony_ci#ifndef PANDA_BUILD 417b8021494Sopenharmony_ci explicit Literal(const T& value, 418b8021494Sopenharmony_ci PlacementPolicy placement_policy = kPlacedWhenUsed, 419b8021494Sopenharmony_ci DeletionPolicy deletion_policy = kManuallyDeleted) 420b8021494Sopenharmony_ci : RawLiteral(&value_, sizeof(T), placement_policy, deletion_policy), 421b8021494Sopenharmony_ci value_(value) {} 422b8021494Sopenharmony_ci explicit Literal(const T& value, DeletionPolicy deletion_policy) 423b8021494Sopenharmony_ci : RawLiteral(&value_, sizeof(T), deletion_policy), value_(value) {} 424b8021494Sopenharmony_ci#else 425b8021494Sopenharmony_ciexplicit Literal(const T& , 426b8021494Sopenharmony_ci PlacementPolicy placement_policy = kPlacedWhenUsed, 427b8021494Sopenharmony_ci DeletionPolicy deletion_policy = kManuallyDeleted) = delete; 428b8021494Sopenharmony_ciexplicit Literal(const T& value, DeletionPolicy deletion_policy) = delete; 429b8021494Sopenharmony_ciexplicit Literal(AllocatorWrapper allocator, const T& value, 430b8021494Sopenharmony_ci PlacementPolicy placement_policy = kPlacedWhenUsed, 431b8021494Sopenharmony_ci DeletionPolicy deletion_policy = kManuallyDeleted) 432b8021494Sopenharmony_ci : RawLiteral(allocator, &value_, sizeof(T), placement_policy, deletion_policy), 433b8021494Sopenharmony_ci value_(value) {} 434b8021494Sopenharmony_ciexplicit Literal(AllocatorWrapper allocator, const T& value, DeletionPolicy deletion_policy) 435b8021494Sopenharmony_ci : RawLiteral(allocator, &value_, sizeof(T), deletion_policy), value_(value) {} 436b8021494Sopenharmony_ci 437b8021494Sopenharmony_ci#endif 438b8021494Sopenharmony_ci void UpdateValue(const T& value, CodeBuffer* buffer) { 439b8021494Sopenharmony_ci value_ = value; 440b8021494Sopenharmony_ci if (IsBound()) { 441b8021494Sopenharmony_ci buffer->UpdateData(GetLocation(), GetDataAddress(), GetSize()); 442b8021494Sopenharmony_ci } 443b8021494Sopenharmony_ci } 444b8021494Sopenharmony_ci 445b8021494Sopenharmony_ci private: 446b8021494Sopenharmony_ci T value_; 447b8021494Sopenharmony_ci}; 448b8021494Sopenharmony_ci 449b8021494Sopenharmony_ciclass StringLiteral : public RawLiteral { 450b8021494Sopenharmony_ci public: 451b8021494Sopenharmony_ci#ifndef PANDA_BUILD 452b8021494Sopenharmony_ci explicit StringLiteral(const char* str, 453b8021494Sopenharmony_ci PlacementPolicy placement_policy = kPlacedWhenUsed, 454b8021494Sopenharmony_ci DeletionPolicy deletion_policy = kManuallyDeleted) 455b8021494Sopenharmony_ci : RawLiteral(str, 456b8021494Sopenharmony_ci static_cast<int>(strlen(str) + 1), 457b8021494Sopenharmony_ci placement_policy, 458b8021494Sopenharmony_ci deletion_policy) { 459b8021494Sopenharmony_ci VIXL_ASSERT((strlen(str) + 1) <= kMaxObjectSize); 460b8021494Sopenharmony_ci } 461b8021494Sopenharmony_ci explicit StringLiteral(const char* str, DeletionPolicy deletion_policy) 462b8021494Sopenharmony_ci : RawLiteral(str, static_cast<int>(strlen(str) + 1), deletion_policy) { 463b8021494Sopenharmony_ci VIXL_ASSERT((strlen(str) + 1) <= kMaxObjectSize); 464b8021494Sopenharmony_ci } 465b8021494Sopenharmony_ci#else 466b8021494Sopenharmony_ciexplicit StringLiteral(const char* str, 467b8021494Sopenharmony_ci PlacementPolicy placement_policy = kPlacedWhenUsed, 468b8021494Sopenharmony_ci DeletionPolicy deletion_policy = kManuallyDeleted) = delete; 469b8021494Sopenharmony_ciStringLiteral(AllocatorWrapper allocator, const char* str, 470b8021494Sopenharmony_ci PlacementPolicy placement_policy = kPlacedWhenUsed, 471b8021494Sopenharmony_ci DeletionPolicy deletion_policy = kManuallyDeleted) 472b8021494Sopenharmony_ci : RawLiteral(allocator, str, 473b8021494Sopenharmony_ci static_cast<int>(strlen(str) + 1), 474b8021494Sopenharmony_ci placement_policy, 475b8021494Sopenharmony_ci deletion_policy) { 476b8021494Sopenharmony_ci VIXL_ASSERT((strlen(str) + 1) <= kMaxObjectSize); 477b8021494Sopenharmony_ci} 478b8021494Sopenharmony_ciexplicit StringLiteral(const char* str, DeletionPolicy deletion_policy) = delete; 479b8021494Sopenharmony_ciexplicit StringLiteral(AllocatorWrapper allocator, const char* str, DeletionPolicy deletion_policy) 480b8021494Sopenharmony_ci : RawLiteral(allocator, str, static_cast<int>(strlen(str) + 1), deletion_policy) { 481b8021494Sopenharmony_ci VIXL_ASSERT((strlen(str) + 1) <= kMaxObjectSize); 482b8021494Sopenharmony_ci} 483b8021494Sopenharmony_ci#endif 484b8021494Sopenharmony_ci}; 485b8021494Sopenharmony_ci 486b8021494Sopenharmony_ci} // namespace aarch32 487b8021494Sopenharmony_ci 488b8021494Sopenharmony_ci 489b8021494Sopenharmony_ci// Required InvalSet template specialisations. 490b8021494Sopenharmony_ci#define INVAL_SET_TEMPLATE_PARAMETERS \ 491b8021494Sopenharmony_ci aarch32::Location::ForwardRef, aarch32::Location::kNPreallocatedElements, \ 492b8021494Sopenharmony_ci int32_t, aarch32::Location::kInvalidLinkKey, \ 493b8021494Sopenharmony_ci aarch32::Location::kReclaimFrom, aarch32::Location::kReclaimFactor 494b8021494Sopenharmony_citemplate <> 495b8021494Sopenharmony_ciinline int32_t InvalSet<INVAL_SET_TEMPLATE_PARAMETERS>::GetKey( 496b8021494Sopenharmony_ci const aarch32::Location::ForwardRef& element) { 497b8021494Sopenharmony_ci return element.GetLocation(); 498b8021494Sopenharmony_ci} 499b8021494Sopenharmony_citemplate <> 500b8021494Sopenharmony_ciinline void InvalSet<INVAL_SET_TEMPLATE_PARAMETERS>::SetKey( 501b8021494Sopenharmony_ci aarch32::Location::ForwardRef* element, int32_t key) { 502b8021494Sopenharmony_ci element->SetLocationToInvalidateOnly(key); 503b8021494Sopenharmony_ci} 504b8021494Sopenharmony_ci#undef INVAL_SET_TEMPLATE_PARAMETERS 505b8021494Sopenharmony_ci 506b8021494Sopenharmony_ci} // namespace vixl 507b8021494Sopenharmony_ci 508b8021494Sopenharmony_ci#endif // VIXL_AARCH32_LABEL_AARCH32_H_ 509