1 // AsmJit - Machine code generation for C++ 2 // 3 // * Official AsmJit Home Page: https://asmjit.com 4 // * Official Github Repository: https://github.com/asmjit/asmjit 5 // 6 // Copyright (c) 2008-2020 The AsmJit Authors 7 // 8 // This software is provided 'as-is', without any express or implied 9 // warranty. In no event will the authors be held liable for any damages 10 // arising from the use of this software. 11 // 12 // Permission is granted to anyone to use this software for any purpose, 13 // including commercial applications, and to alter it and redistribute it 14 // freely, subject to the following restrictions: 15 // 16 // 1. The origin of this software must not be misrepresented; you must not 17 // claim that you wrote the original software. If you use this software 18 // in a product, an acknowledgment in the product documentation would be 19 // appreciated but is not required. 20 // 2. Altered source versions must be plainly marked as such, and must not be 21 // misrepresented as being the original software. 22 // 3. This notice may not be removed or altered from any source distribution. 23 24 #ifndef ASMJIT_CORE_RASTACK_P_H_INCLUDED 25 #define ASMJIT_CORE_RASTACK_P_H_INCLUDED 26 27 #include "../core/api-config.h" 28 #ifndef ASMJIT_NO_COMPILER 29 30 #include "../core/radefs_p.h" 31 32 ASMJIT_BEGIN_NAMESPACE 33 34 //! \cond INTERNAL 35 //! \addtogroup asmjit_ra 36 //! \{ 37 38 // ============================================================================ 39 // [asmjit::RAStackSlot] 40 // ============================================================================ 41 42 //! Stack slot. 43 struct RAStackSlot { 44 //! Stack slot flags. 45 //! 46 //! TODO: kFlagStackArg is not used by the current implementation, do we need to keep it? 47 enum Flags : uint32_t { 48 //! Stack slot is register home slot. 49 kFlagRegHome = 0x0001u, 50 //! Stack slot position matches argument passed via stack. 51 kFlagStackArg = 0x0002u 52 }; 53 54 enum ArgIndex : uint32_t { 55 kNoArgIndex = 0xFF 56 }; 57 58 //! Base register used to address the stack. 59 uint8_t _baseRegId; 60 //! Minimum alignment required by the slot. 61 uint8_t _alignment; 62 //! Reserved for future use. 63 uint16_t _flags; 64 //! Size of memory required by the slot. 65 uint32_t _size; 66 67 //! Usage counter (one unit equals one memory access). 68 uint32_t _useCount; 69 //! Weight of the slot, calculated by \ref RAStackAllocator::calculateStackFrame(). 70 uint32_t _weight; 71 //! Stack offset, calculated by \ref RAStackAllocator::calculateStackFrame(). 72 int32_t _offset; 73 74 //! \name Accessors 75 //! \{ 76 baseRegIdRAStackSlot77 inline uint32_t baseRegId() const noexcept { return _baseRegId; } setBaseRegIdRAStackSlot78 inline void setBaseRegId(uint32_t id) noexcept { _baseRegId = uint8_t(id); } 79 sizeRAStackSlot80 inline uint32_t size() const noexcept { return _size; } alignmentRAStackSlot81 inline uint32_t alignment() const noexcept { return _alignment; } 82 flagsRAStackSlot83 inline uint32_t flags() const noexcept { return _flags; } hasFlagRAStackSlot84 inline bool hasFlag(uint32_t flag) const noexcept { return (_flags & flag) != 0; } addFlagsRAStackSlot85 inline void addFlags(uint32_t flags) noexcept { _flags = uint16_t(_flags | flags); } 86 isRegHomeRAStackSlot87 inline bool isRegHome() const noexcept { return hasFlag(kFlagRegHome); } isStackArgRAStackSlot88 inline bool isStackArg() const noexcept { return hasFlag(kFlagStackArg); } 89 useCountRAStackSlot90 inline uint32_t useCount() const noexcept { return _useCount; } 91 inline void addUseCount(uint32_t n = 1) noexcept { _useCount += n; } 92 weightRAStackSlot93 inline uint32_t weight() const noexcept { return _weight; } setWeightRAStackSlot94 inline void setWeight(uint32_t weight) noexcept { _weight = weight; } 95 offsetRAStackSlot96 inline int32_t offset() const noexcept { return _offset; } setOffsetRAStackSlot97 inline void setOffset(int32_t offset) noexcept { _offset = offset; } 98 99 //! \} 100 }; 101 102 typedef ZoneVector<RAStackSlot*> RAStackSlots; 103 104 // ============================================================================ 105 // [asmjit::RAStackAllocator] 106 // ============================================================================ 107 108 //! Stack allocator. 109 class RAStackAllocator { 110 public: 111 ASMJIT_NONCOPYABLE(RAStackAllocator) 112 113 enum Size : uint32_t { 114 kSize1 = 0, 115 kSize2 = 1, 116 kSize4 = 2, 117 kSize8 = 3, 118 kSize16 = 4, 119 kSize32 = 5, 120 kSize64 = 6, 121 kSizeCount = 7 122 }; 123 124 //! Allocator used to allocate internal data. 125 ZoneAllocator* _allocator; 126 //! Count of bytes used by all slots. 127 uint32_t _bytesUsed; 128 //! Calculated stack size (can be a bit greater than `_bytesUsed`). 129 uint32_t _stackSize; 130 //! Minimum stack alignment. 131 uint32_t _alignment; 132 //! Stack slots vector. 133 RAStackSlots _slots; 134 135 //! \name Construction / Destruction 136 //! \{ 137 RAStackAllocator()138 inline RAStackAllocator() noexcept 139 : _allocator(nullptr), 140 _bytesUsed(0), 141 _stackSize(0), 142 _alignment(1), 143 _slots() {} 144 reset(ZoneAllocator * allocator)145 inline void reset(ZoneAllocator* allocator) noexcept { 146 _allocator = allocator; 147 _bytesUsed = 0; 148 _stackSize = 0; 149 _alignment = 1; 150 _slots.reset(); 151 } 152 153 //! \} 154 155 //! \name Accessors 156 //! \{ 157 allocator()158 inline ZoneAllocator* allocator() const noexcept { return _allocator; } 159 bytesUsed()160 inline uint32_t bytesUsed() const noexcept { return _bytesUsed; } stackSize()161 inline uint32_t stackSize() const noexcept { return _stackSize; } alignment()162 inline uint32_t alignment() const noexcept { return _alignment; } 163 slots()164 inline RAStackSlots& slots() noexcept { return _slots; } slots()165 inline const RAStackSlots& slots() const noexcept { return _slots; } slotCount()166 inline uint32_t slotCount() const noexcept { return _slots.size(); } 167 168 //! \} 169 170 //! \name Utilities 171 //! \{ 172 173 RAStackSlot* newSlot(uint32_t baseRegId, uint32_t size, uint32_t alignment, uint32_t flags = 0) noexcept; 174 175 Error calculateStackFrame() noexcept; 176 Error adjustSlotOffsets(int32_t offset) noexcept; 177 178 //! \} 179 }; 180 181 //! \} 182 //! \endcond 183 184 ASMJIT_END_NAMESPACE 185 186 #endif // !ASMJIT_NO_COMPILER 187 #endif // ASMJIT_CORE_RASTACK_P_H_INCLUDED 188