Welcome to mirror list, hosted at ThFree Co, Russian Federation.

rastack_p.h « core « asmjit « src - github.com/asmjit/asmjit.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 90640b4dea897129efd29cf17bf341fda4d9dfa9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
// This file is part of AsmJit project <https://asmjit.com>
//
// See asmjit.h or LICENSE.md for license and copyright information
// SPDX-License-Identifier: Zlib

#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
//! \{

//! Stack slot.
struct RAStackSlot {
  //! Stack slot flags.
  //!
  //! TODO: kFlagStackArg is not used by the current implementation, do we need to keep it?
  enum Flags : uint16_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
  };

  //! \name Members
  //! \{

  //! 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;

//! 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
  };

  //! \name Members
  //! \{

  //! 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