1 // [AsmJit]
2 // Machine Code Generation for C++.
3 //
4 // [License]
5 // Zlib - See LICENSE.md file in the package.
6 
7 #ifndef _ASMJIT_CORE_TARGET_H
8 #define _ASMJIT_CORE_TARGET_H
9 
10 #include "../core/arch.h"
11 #include "../core/func.h"
12 
13 ASMJIT_BEGIN_NAMESPACE
14 
15 //! \addtogroup asmjit_core
16 //! \{
17 
18 // ============================================================================
19 // [asmjit::CodeInfo]
20 // ============================================================================
21 
22 //! Basic information about a code (or target). It describes its architecture,
23 //! code generation mode (or optimization level), and base address.
24 class CodeInfo {
25 public:
26   //!< Architecture information.
27   ArchInfo _archInfo;
28   //! Natural stack alignment (ARCH+OS).
29   uint8_t _stackAlignment;
30   //! Default CDECL calling convention.
31   uint8_t _cdeclCallConv;
32   //! Default STDCALL calling convention.
33   uint8_t _stdCallConv;
34   //! Default FASTCALL calling convention.
35   uint8_t _fastCallConv;
36   //! Base address.
37   uint64_t _baseAddress;
38 
39   //! \name Construction & Destruction
40   //! \{
41 
CodeInfo()42   inline CodeInfo() noexcept
43     : _archInfo(),
44       _stackAlignment(0),
45       _cdeclCallConv(CallConv::kIdNone),
46       _stdCallConv(CallConv::kIdNone),
47       _fastCallConv(CallConv::kIdNone),
48       _baseAddress(Globals::kNoBaseAddress) {}
49 
50   inline explicit CodeInfo(uint32_t archId, uint32_t archMode = 0, uint64_t baseAddress = Globals::kNoBaseAddress) noexcept
_archInfo(archId,archMode)51     : _archInfo(archId, archMode),
52       _stackAlignment(0),
53       _cdeclCallConv(CallConv::kIdNone),
54       _stdCallConv(CallConv::kIdNone),
55       _fastCallConv(CallConv::kIdNone),
56       _baseAddress(baseAddress) {}
57 
CodeInfo(const CodeInfo & other)58   inline CodeInfo(const CodeInfo& other) noexcept { init(other); }
59 
isInitialized()60   inline bool isInitialized() const noexcept {
61     return _archInfo.archId() != ArchInfo::kIdNone;
62   }
63 
init(const CodeInfo & other)64   inline void init(const CodeInfo& other) noexcept {
65     *this = other;
66   }
67 
68   inline void init(uint32_t archId, uint32_t archMode = 0, uint64_t baseAddress = Globals::kNoBaseAddress) noexcept {
69     _archInfo.init(archId, archMode);
70     _stackAlignment = 0;
71     _cdeclCallConv = CallConv::kIdNone;
72     _stdCallConv = CallConv::kIdNone;
73     _fastCallConv = CallConv::kIdNone;
74     _baseAddress = baseAddress;
75   }
76 
reset()77   inline void reset() noexcept {
78     _archInfo.reset();
79     _stackAlignment = 0;
80     _cdeclCallConv = CallConv::kIdNone;
81     _stdCallConv = CallConv::kIdNone;
82     _fastCallConv = CallConv::kIdNone;
83     _baseAddress = Globals::kNoBaseAddress;
84   }
85 
86   //! \}
87 
88   //! \name Overloaded Operators
89   //! \{
90 
91   inline CodeInfo& operator=(const CodeInfo& other) noexcept = default;
92 
93   inline bool operator==(const CodeInfo& other) const noexcept { return ::memcmp(this, &other, sizeof(*this)) == 0; }
94   inline bool operator!=(const CodeInfo& other) const noexcept { return ::memcmp(this, &other, sizeof(*this)) != 0; }
95 
96   //! \}
97 
98   //! \name Accessors
99   //! \{
100 
101   //! Returns the target architecture information, see `ArchInfo`.
archInfo()102   inline const ArchInfo& archInfo() const noexcept { return _archInfo; }
103 
104   //! Returns the target architecture id, see `ArchInfo::Id`.
archId()105   inline uint32_t archId() const noexcept { return _archInfo.archId(); }
106   //! Returns the target architecture sub-type, see `ArchInfo::SubId`.
archSubId()107   inline uint32_t archSubId() const noexcept { return _archInfo.archSubId(); }
108   //! Returns the native size of the target's architecture GP register.
gpSize()109   inline uint32_t gpSize() const noexcept { return _archInfo.gpSize(); }
110   //! Returns the number of GP registers of the target's architecture.
gpCount()111   inline uint32_t gpCount() const noexcept { return _archInfo.gpCount(); }
112 
113   //! Returns a natural stack alignment that must be honored (or 0 if not known).
stackAlignment()114   inline uint32_t stackAlignment() const noexcept { return _stackAlignment; }
115   //! Sets a natural stack alignment that must be honored.
setStackAlignment(uint32_t sa)116   inline void setStackAlignment(uint32_t sa) noexcept { _stackAlignment = uint8_t(sa); }
117 
cdeclCallConv()118   inline uint32_t cdeclCallConv() const noexcept { return _cdeclCallConv; }
setCdeclCallConv(uint32_t cc)119   inline void setCdeclCallConv(uint32_t cc) noexcept { _cdeclCallConv = uint8_t(cc); }
120 
stdCallConv()121   inline uint32_t stdCallConv() const noexcept { return _stdCallConv; }
setStdCallConv(uint32_t cc)122   inline void setStdCallConv(uint32_t cc) noexcept { _stdCallConv = uint8_t(cc); }
123 
fastCallConv()124   inline uint32_t fastCallConv() const noexcept { return _fastCallConv; }
setFastCallConv(uint32_t cc)125   inline void setFastCallConv(uint32_t cc) noexcept { _fastCallConv = uint8_t(cc); }
126 
hasBaseAddress()127   inline bool hasBaseAddress() const noexcept { return _baseAddress != Globals::kNoBaseAddress; }
baseAddress()128   inline uint64_t baseAddress() const noexcept { return _baseAddress; }
setBaseAddress(uint64_t p)129   inline void setBaseAddress(uint64_t p) noexcept { _baseAddress = p; }
resetBaseAddress()130   inline void resetBaseAddress() noexcept { _baseAddress = Globals::kNoBaseAddress; }
131 
132   //! \}
133 };
134 
135 // ============================================================================
136 // [asmjit::Target]
137 // ============================================================================
138 
139 //! Target is an abstract class that describes a machine code target.
140 class ASMJIT_VIRTAPI Target {
141 public:
142   ASMJIT_BASE_CLASS(Target)
143   ASMJIT_NONCOPYABLE(Target)
144 
145   //! Tartget type, see `TargetType`.
146   uint8_t _targetType;
147   //! Reserved for future use.
148   uint8_t _reserved[7];
149   //! Basic information about the Runtime's code.
150   CodeInfo _codeInfo;
151 
152   enum TargetType : uint32_t {
153     //! Uninitialized target or unknown target type.
154     kTargetNone = 0,
155     //! JIT target type, see `JitRuntime`.
156     kTargetJit = 1
157   };
158 
159   //! \name Construction & Destruction
160   //! \{
161 
162   //! Creates a `Target` instance.
163   ASMJIT_API Target() noexcept;
164   //! Destroys the `Target` instance.
165   ASMJIT_API virtual ~Target() noexcept;
166 
167   //! \}
168 
169   //! \name Accessors
170   //! \{
171 
172   //! Returns CodeInfo of this target.
173   //!
174   //! CodeInfo can be used to setup a CodeHolder in case you plan to generate a
175   //! code compatible and executable by this Runtime.
codeInfo()176   inline const CodeInfo& codeInfo() const noexcept { return _codeInfo; }
177 
178   //! Returns the target architecture id, see `ArchInfo::Id`.
archId()179   inline uint32_t archId() const noexcept { return _codeInfo.archId(); }
180   //! Returns the target architecture sub-id, see `ArchInfo::SubId`.
archSubId()181   inline uint32_t archSubId() const noexcept { return _codeInfo.archSubId(); }
182 
183   //! Returns the target type, see `TargetType`.
targetType()184   inline uint32_t targetType() const noexcept { return _targetType; }
185 
186   //! \}
187 };
188 
189 //! \}
190 
191 ASMJIT_END_NAMESPACE
192 
193 #endif // _ASMJIT_CORE_TARGET_H
194