You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Theodosius/dependencies/asmjit/core/rastack_p.h

188 lines
5.6 KiB

// AsmJit - Machine code generation for C++
//
// * Official AsmJit Home Page: https://asmjit.com
// * Official Github Repository: https://github.com/asmjit/asmjit
//
// Copyright (c) 2008-2020 The AsmJit Authors
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be
// appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.
#ifndef ASMJIT_CORE_RASTACK_P_H_INCLUDED
#define ASMJIT_CORE_RASTACK_P_H_INCLUDED
#include "../core/api-config.h"
#ifndef ASMJIT_NO_COMPILER
#include "../core/radefs_p.h"
ASMJIT_BEGIN_NAMESPACE
//! \cond INTERNAL
//! \addtogroup asmjit_ra
//! \{
// ============================================================================
// [asmjit::RAStackSlot]
// ============================================================================
//! Stack slot.
struct RAStackSlot {
//! Stack slot flags.
//!
//! TODO: kFlagStackArg is not used by the current implementation, do we need to keep it?
enum Flags : uint32_t {
//! Stack slot is register home slot.
kFlagRegHome = 0x0001u,
//! Stack slot position matches argument passed via stack.
kFlagStackArg = 0x0002u
};
enum ArgIndex : uint32_t {
kNoArgIndex = 0xFF
};
//! Base register used to address the stack.
uint8_t _baseRegId;
//! Minimum alignment required by the slot.
uint8_t _alignment;
//! Reserved for future use.
uint16_t _flags;
//! Size of memory required by the slot.
uint32_t _size;
//! Usage counter (one unit equals one memory access).
uint32_t _useCount;
//! Weight of the slot, calculated by \ref RAStackAllocator::calculateStackFrame().
uint32_t _weight;
//! Stack offset, calculated by \ref RAStackAllocator::calculateStackFrame().
int32_t _offset;
//! \name Accessors
//! \{
inline uint32_t baseRegId() const noexcept { return _baseRegId; }
inline void setBaseRegId(uint32_t id) noexcept { _baseRegId = uint8_t(id); }
inline uint32_t size() const noexcept { return _size; }
inline uint32_t alignment() const noexcept { return _alignment; }
inline uint32_t flags() const noexcept { return _flags; }
inline bool hasFlag(uint32_t flag) const noexcept { return (_flags & flag) != 0; }
inline void addFlags(uint32_t flags) noexcept { _flags = uint16_t(_flags | flags); }
inline bool isRegHome() const noexcept { return hasFlag(kFlagRegHome); }
inline bool isStackArg() const noexcept { return hasFlag(kFlagStackArg); }
inline uint32_t useCount() const noexcept { return _useCount; }
inline void addUseCount(uint32_t n = 1) noexcept { _useCount += n; }
inline uint32_t weight() const noexcept { return _weight; }
inline void setWeight(uint32_t weight) noexcept { _weight = weight; }
inline int32_t offset() const noexcept { return _offset; }
inline void setOffset(int32_t offset) noexcept { _offset = offset; }
//! \}
};
typedef ZoneVector<RAStackSlot*> RAStackSlots;
// ============================================================================
// [asmjit::RAStackAllocator]
// ============================================================================
//! Stack allocator.
class RAStackAllocator {
public:
ASMJIT_NONCOPYABLE(RAStackAllocator)
enum Size : uint32_t {
kSize1 = 0,
kSize2 = 1,
kSize4 = 2,
kSize8 = 3,
kSize16 = 4,
kSize32 = 5,
kSize64 = 6,
kSizeCount = 7
};
//! Allocator used to allocate internal data.
ZoneAllocator* _allocator;
//! Count of bytes used by all slots.
uint32_t _bytesUsed;
//! Calculated stack size (can be a bit greater than `_bytesUsed`).
uint32_t _stackSize;
//! Minimum stack alignment.
uint32_t _alignment;
//! Stack slots vector.
RAStackSlots _slots;
//! \name Construction / Destruction
//! \{
inline RAStackAllocator() noexcept
: _allocator(nullptr),
_bytesUsed(0),
_stackSize(0),
_alignment(1),
_slots() {}
inline void reset(ZoneAllocator* allocator) noexcept {
_allocator = allocator;
_bytesUsed = 0;
_stackSize = 0;
_alignment = 1;
_slots.reset();
}
//! \}
//! \name Accessors
//! \{
inline ZoneAllocator* allocator() const noexcept { return _allocator; }
inline uint32_t bytesUsed() const noexcept { return _bytesUsed; }
inline uint32_t stackSize() const noexcept { return _stackSize; }
inline uint32_t alignment() const noexcept { return _alignment; }
inline RAStackSlots& slots() noexcept { return _slots; }
inline const RAStackSlots& slots() const noexcept { return _slots; }
inline uint32_t slotCount() const noexcept { return _slots.size(); }
//! \}
//! \name Utilities
//! \{
RAStackSlot* newSlot(uint32_t baseRegId, uint32_t size, uint32_t alignment, uint32_t flags = 0) noexcept;
Error calculateStackFrame() noexcept;
Error adjustSlotOffsets(int32_t offset) noexcept;
//! \}
};
//! \}
//! \endcond
ASMJIT_END_NAMESPACE
#endif // !ASMJIT_NO_COMPILER
#endif // ASMJIT_CORE_RASTACK_P_H_INCLUDED