1 // [AsmJit]
2 // Complete JIT Assembler for C++ Language.
3 //
4 // [License]
5 // Zlib - See COPYING file in this package.
6 
7 // [Guard]
8 #ifndef _ASMJIT_CORE_COMPILERFUNC_H
9 #define _ASMJIT_CORE_COMPILERFUNC_H
10 
11 // [Dependencies - AsmJit]
12 #include "../core/compiler.h"
13 #include "../core/compileritem.h"
14 
15 // [Api-Begin]
16 #include "../core/apibegin.h"
17 
18 namespace AsmJit {
19 
20 // ============================================================================
21 // [AsmJit::CompilerFuncDecl]
22 // ============================================================================
23 
24 //! @brief Compiler function declaration item.
25 //!
26 //! Functions are base blocks for generating assembler output. Each generated
27 //! assembler stream needs standard entry and leave sequences thats compatible
28 //! with the operating system conventions (ABI).
29 //!
30 //! Function class can be used to generate function prolog) and epilog sequences
31 //! that are compatible with the demanded calling convention and to allocate and
32 //! manage variables that can be allocated/spilled during compilation time.
33 //!
34 //! @note To create a function use @c Compiler::newFunc() method, do not
35 //! create any form of compiler function items using new operator.
36 //!
37 //! @sa @ref CompilerState, @ref CompilerVar.
38 struct CompilerFuncDecl : public CompilerItem
39 {
40   // --------------------------------------------------------------------------
41   // [Construction / Destruction]
42   // --------------------------------------------------------------------------
43 
44   //! @brief Create a new @c CompilerFuncDecl instance.
45   //!
46   //! @note Always use @c AsmJit::Compiler::newFunc() to create @c Function
47   //! instance.
48   ASMJIT_API CompilerFuncDecl(Compiler* compiler);
49   //! @brief Destroy the @c CompilerFuncDecl instance.
50   ASMJIT_API virtual ~CompilerFuncDecl();
51 
52   // --------------------------------------------------------------------------
53   // [Accessors]
54   // --------------------------------------------------------------------------
55 
56   //! @brief Get function entry label.
57   //!
58   //! Entry label can be used to call this function from another code that's
59   //! being generated.
getEntryLabelCompilerFuncDecl60   inline const Label& getEntryLabel() const
61   { return _entryLabel; }
62 
63   //! @brief Get function exit label.
64   //!
65   //! Use exit label to jump to function epilog.
getExitLabelCompilerFuncDecl66   inline const Label& getExitLabel() const
67   { return _exitLabel; }
68 
69   //! @brief Get function entry target.
getEntryTargetCompilerFuncDecl70   inline CompilerTarget* getEntryTarget() const
71   { return _entryTarget; }
72 
73   //! @brief Get function exit target.
getExitTargetCompilerFuncDecl74   inline CompilerTarget* getExitTarget() const
75   { return _exitTarget; }
76 
77   //! @brief Get function end item.
getEndCompilerFuncDecl78   inline CompilerFuncEnd* getEnd() const
79   { return _end; }
80 
81   //! @brief Get function declaration.
getDeclCompilerFuncDecl82   inline FuncDecl* getDecl() const
83   { return _decl; }
84 
85   //! @brief Get function arguments as variables.
getVarsCompilerFuncDecl86   inline CompilerVar** getVars() const
87   { return _vars; }
88 
89   //! @brief Get function argument at @a index.
getVarCompilerFuncDecl90   inline CompilerVar* getVar(uint32_t index) const
91   {
92     ASMJIT_ASSERT(index < _decl->getArgumentsCount());
93     return _vars[index];
94   }
95 
96   //! @brief Get function hints.
getFuncHintsCompilerFuncDecl97   inline uint32_t getFuncHints() const
98   { return _funcHints; }
99 
100   //! @brief Get function flags.
getFuncFlagsCompilerFuncDecl101   inline uint32_t getFuncFlags() const
102   { return _funcFlags; }
103 
104   //! @brief Get whether the _funcFlags has @a flag
hasFuncFlagCompilerFuncDecl105   inline bool hasFuncFlag(uint32_t flag) const
106   { return (_funcFlags & flag) != 0; }
107 
108   //! @brief Set function @a flag.
setFuncFlagCompilerFuncDecl109   inline void setFuncFlag(uint32_t flag)
110   { _funcFlags |= flag; }
111 
112   //! @brief Clear function @a flag.
clearFuncFlagCompilerFuncDecl113   inline void clearFuncFlag(uint32_t flag)
114   { _funcFlags &= ~flag; }
115 
116   //! @brief Get whether the function is also a caller.
isCallerCompilerFuncDecl117   inline bool isCaller() const
118   { return hasFuncFlag(kFuncFlagIsCaller); }
119 
120   //! @brief Get whether the function is finished.
isFinishedCompilerFuncDecl121   inline bool isFinished() const
122   { return hasFuncFlag(kFuncFlagIsFinished); }
123 
124   //! @brief Get whether the function is naked.
isNakedCompilerFuncDecl125   inline bool isNaked() const
126   { return hasFuncFlag(kFuncFlagIsNaked); }
127 
128   //! @brief Get stack size needed to call other functions.
getFuncCallStackSizeCompilerFuncDecl129   inline int32_t getFuncCallStackSize() const
130   { return _funcCallStackSize; }
131 
132   // --------------------------------------------------------------------------
133   // [Hints]
134   // --------------------------------------------------------------------------
135 
136   //! @brief Set function hint.
137   ASMJIT_API virtual void setHint(uint32_t hint, uint32_t value);
138   //! @brief Get function hint.
139   ASMJIT_API virtual uint32_t getHint(uint32_t hint) const;
140 
141   // --------------------------------------------------------------------------
142   // [Prototype]
143   // --------------------------------------------------------------------------
144 
145   virtual void setPrototype(
146     uint32_t convention,
147     uint32_t returnType,
148     const uint32_t* arguments,
149     uint32_t argumentsCount) = 0;
150 
151   // --------------------------------------------------------------------------
152   // [Members]
153   // --------------------------------------------------------------------------
154 
155   //! @brief Function entry label.
156   Label _entryLabel;
157   //! @brief Function exit label.
158   Label _exitLabel;
159 
160   //! @brief Function entry target.
161   CompilerTarget* _entryTarget;
162   //! @brief Function exit target.
163   CompilerTarget* _exitTarget;
164 
165   //! @brief Function end item.
166   CompilerFuncEnd* _end;
167 
168   //! @brief Function declaration.
169   FuncDecl* _decl;
170   //! @brief Function arguments as compiler variables.
171   CompilerVar** _vars;
172 
173   //! @brief Function hints;
174   uint32_t _funcHints;
175   //! @brief Function flags.
176   uint32_t _funcFlags;
177 
178   //! @brief Stack size needed to call other functions.
179   int32_t _funcCallStackSize;
180 };
181 
182 // ============================================================================
183 // [AsmJit::CompilerFuncEnd]
184 // ============================================================================
185 
186 //! @brief Compiler function end item.
187 //!
188 //! This item does nothing; it's only used by @ref Compiler to mark  specific
189 //! location in the code. The @c CompilerFuncEnd is similar to @c CompilerMark,
190 //! except that it overrides @c translate() to return @c NULL.
191 struct CompilerFuncEnd : public CompilerItem
192 {
193   ASMJIT_NO_COPY(CompilerFuncEnd)
194 
195   // --------------------------------------------------------------------------
196   // [Construction / Destruction]
197   // --------------------------------------------------------------------------
198 
199   //! @brief Create a new @ref CompilerMark instance.
200   ASMJIT_API CompilerFuncEnd(Compiler* compiler, CompilerFuncDecl* func);
201   //! @brief Destroy the @ref CompilerMark instance.
202   ASMJIT_API virtual ~CompilerFuncEnd();
203 
204   // --------------------------------------------------------------------------
205   // [Accessors]
206   // --------------------------------------------------------------------------
207 
208   //! @brief Get related function.
getFuncCompilerFuncEnd209   inline CompilerFuncDecl* getFunc() const
210   { return _func; }
211 
212   // --------------------------------------------------------------------------
213   // [Interface]
214   // --------------------------------------------------------------------------
215 
216   ASMJIT_API virtual CompilerItem* translate(CompilerContext& cc);
217 
218   // --------------------------------------------------------------------------
219   // [Members]
220   // --------------------------------------------------------------------------
221 
222   //! @brief Related function.
223   CompilerFuncDecl* _func;
224 };
225 
226 // ============================================================================
227 // [AsmJit::CompilerFuncRet]
228 // ============================================================================
229 
230 //! @brief Compiler return from function item.
231 struct CompilerFuncRet : public CompilerItem
232 {
233   ASMJIT_NO_COPY(CompilerFuncRet)
234 
235   // --------------------------------------------------------------------------
236   // [Construction / Destruction]
237   // --------------------------------------------------------------------------
238 
239   //! @brief Create a new @ref CompilerFuncRet instance.
240   ASMJIT_API CompilerFuncRet(Compiler* compiler, CompilerFuncDecl* func,
241     const Operand* first, const Operand* second);
242   //! @brief Destroy the @ref CompilerFuncRet instance.
243   ASMJIT_API virtual ~CompilerFuncRet();
244 
245   // --------------------------------------------------------------------------
246   // [Accessors]
247   // --------------------------------------------------------------------------
248 
249   //! @Brief Get the related function.
getFuncCompilerFuncRet250   inline CompilerFuncDecl* getFunc() const
251   { return _func; }
252 
253   //! @brief Get the first return operand.
getFirstCompilerFuncRet254   inline Operand& getFirst()
255   { return _ret[0]; }
256 
257   //! @overload
getFirstCompilerFuncRet258   inline const Operand& getFirst() const
259   { return _ret[0]; }
260 
261   //! @brief Get the second return operand.
getSecondCompilerFuncRet262   inline Operand& getSecond()
263   { return _ret[1]; }
264 
265   //! @overload
getSecondCompilerFuncRet266   inline const Operand& getSecond() const
267   { return _ret[1]; }
268 
269   // --------------------------------------------------------------------------
270   // [Misc]
271   // --------------------------------------------------------------------------
272 
273   //! @brief Get whether jump to epilog has to be emitted.
274   ASMJIT_API bool mustEmitJump() const;
275 
276   // --------------------------------------------------------------------------
277   // [Members]
278   // --------------------------------------------------------------------------
279 
280   //! @brief Related function.
281   CompilerFuncDecl* _func;
282   //! @brief Return operand(s).
283   Operand _ret[2];
284 };
285 
286 // ============================================================================
287 // [AsmJit::CompilerFuncCall]
288 // ============================================================================
289 
290 //! @brief Compiler function call item.
291 struct CompilerFuncCall : public CompilerItem
292 {
293   ASMJIT_NO_COPY(CompilerFuncCall)
294 
295   // --------------------------------------------------------------------------
296   // [Construction / Destruction]
297   // --------------------------------------------------------------------------
298 
299   //! @brief Create a new @ref CompilerFuncCall instance.
300   ASMJIT_API CompilerFuncCall(Compiler* compiler, CompilerFuncDecl* caller, const Operand* target);
301   //! @brief Destroy the @ref CompilerFuncCall instance.
302   ASMJIT_API virtual ~CompilerFuncCall();
303 
304   // --------------------------------------------------------------------------
305   // [Accessors]
306   // --------------------------------------------------------------------------
307 
308   //! @brief Get caller.
getCallerCompilerFuncCall309   inline CompilerFuncDecl* getCaller() const
310   { return _caller; }
311 
312   //! @brief Get function declaration.
getDeclCompilerFuncCall313   inline FuncDecl* getDecl() const
314   { return _decl; }
315 
316   //! @brief Get target operand.
getTargetCompilerFuncCall317   inline Operand& getTarget()
318   { return _target; }
319 
320   //! @overload
getTargetCompilerFuncCall321   inline const Operand& getTarget() const
322   { return _target; }
323 
324   // --------------------------------------------------------------------------
325   // [Prototype]
326   // --------------------------------------------------------------------------
327 
328   virtual void setPrototype(uint32_t convention, uint32_t returnType, const uint32_t* arguments, uint32_t argumentsCount) = 0;
329 
330   //! @brief Set function prototype.
setPrototypeCompilerFuncCall331   inline void setPrototype(uint32_t convention, const FuncPrototype& func)
332   { setPrototype(convention, func.getReturnType(), func.getArguments(), func.getArgumentsCount()); }
333 
334   // --------------------------------------------------------------------------
335   // [Members]
336   // --------------------------------------------------------------------------
337 
338   //! @brief Caller (the function which does the call).
339   CompilerFuncDecl* _caller;
340   //! @brief Function declaration.
341   FuncDecl* _decl;
342 
343   //! @brief Operand (address of function, register, label, ...).
344   Operand _target;
345   //! @brief Return operands.
346   Operand _ret[2];
347   //! @brief Arguments operands.
348   Operand* _args;
349 };
350 
351 } // AsmJit namespace
352 
353 // [Api-End]
354 #include "../core/apiend.h"
355 
356 // [Guard]
357 #endif // _ASMJIT_CORE_COMPILERFUNC_H
358