/Src/Dependencies/AsmJit/AsmJit/CompilerX86X64.h

http://hadesmem.googlecode.com/ · C Header · 1735 lines · 594 code · 357 blank · 784 comment · 14 complexity · 48e24a65850dc4ef4d9ed95e49313187 MD5 · raw file

Large files are truncated click here to view the full file

  1. // AsmJit - Complete JIT Assembler for C++ Language.
  2. // Copyright (c) 2008-2010, Petr Kobalicek <kobalicek.petr@gmail.com>
  3. //
  4. // Permission is hereby granted, free of charge, to any person
  5. // obtaining a copy of this software and associated documentation
  6. // files (the "Software"), to deal in the Software without
  7. // restriction, including without limitation the rights to use,
  8. // copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the
  10. // Software is furnished to do so, subject to the following
  11. // conditions:
  12. //
  13. // The above copyright notice and this permission notice shall be
  14. // included in all copies or substantial portions of the Software.
  15. //
  16. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  17. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  18. // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  19. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  20. // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  21. // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  22. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  23. // OTHER DEALINGS IN THE SOFTWARE.
  24. // [Guard]
  25. #ifndef _ASMJIT_COMPILERX86X64_H
  26. #define _ASMJIT_COMPILERX86X64_H
  27. #if !defined(_ASMJIT_COMPILER_H)
  28. #warning "AsmJit/CompilerX86X64.h can be only included by AsmJit/Compiler.h"
  29. #endif // _ASMJIT_COMPILER_H
  30. // [Dependencies]
  31. #include "Build.h"
  32. #include "Assembler.h"
  33. #include "Defs.h"
  34. #include "Operand.h"
  35. #include "Util.h"
  36. #include <string.h>
  37. // A little bit C++.
  38. #include <new>
  39. // [Api-Begin]
  40. #include "ApiBegin.h"
  41. //! @internal
  42. //!
  43. //! @brief Mark methods not supported by @ref Compiler. These methods are
  44. //! usually used only in function prologs/epilogs or to manage stack.
  45. #define ASMJIT_NOT_SUPPORTED_BY_COMPILER 0
  46. namespace AsmJit {
  47. //! @addtogroup AsmJit_Compiler
  48. //! @{
  49. // ============================================================================
  50. // [Forward Declarations]
  51. // ============================================================================
  52. struct CodeGenerator;
  53. // ============================================================================
  54. // [AsmJit::TypeToId]
  55. // ============================================================================
  56. // Skip documenting this.
  57. #if !defined(ASMJIT_NODOC)
  58. ASMJIT_DECLARE_TYPE_AS_ID(int8_t, VARIABLE_TYPE_GPD);
  59. ASMJIT_DECLARE_TYPE_AS_ID(uint8_t, VARIABLE_TYPE_GPD);
  60. ASMJIT_DECLARE_TYPE_AS_ID(int16_t, VARIABLE_TYPE_GPD);
  61. ASMJIT_DECLARE_TYPE_AS_ID(uint16_t, VARIABLE_TYPE_GPD);
  62. ASMJIT_DECLARE_TYPE_AS_ID(int32_t, VARIABLE_TYPE_GPD);
  63. ASMJIT_DECLARE_TYPE_AS_ID(uint32_t, VARIABLE_TYPE_GPD);
  64. #if defined(ASMJIT_X64)
  65. ASMJIT_DECLARE_TYPE_AS_ID(int64_t, VARIABLE_TYPE_GPQ);
  66. ASMJIT_DECLARE_TYPE_AS_ID(uint64_t, VARIABLE_TYPE_GPQ);
  67. #endif // ASMJIT_X64
  68. ASMJIT_DECLARE_TYPE_AS_ID(float, VARIABLE_TYPE_FLOAT);
  69. ASMJIT_DECLARE_TYPE_AS_ID(double, VARIABLE_TYPE_DOUBLE);
  70. #endif // !ASMJIT_NODOC
  71. // ============================================================================
  72. // [AsmJit::FunctionPrototype]
  73. // ============================================================================
  74. //! @brief Calling convention and function argument handling.
  75. struct ASMJIT_API FunctionPrototype
  76. {
  77. // --------------------------------------------------------------------------
  78. // [Construction / Destruction]
  79. // --------------------------------------------------------------------------
  80. //! @brief Create a new @ref FunctionPrototype instance.
  81. FunctionPrototype() ASMJIT_NOTHROW;
  82. //! @brief Destroy the @ref FunctionPrototype instance.
  83. ~FunctionPrototype() ASMJIT_NOTHROW;
  84. // --------------------------------------------------------------------------
  85. // [Argument]
  86. // --------------------------------------------------------------------------
  87. //! @brief Function argument location.
  88. struct Argument
  89. {
  90. //! @brief Variable type, see @c VARIABLE_TYPE.
  91. uint32_t variableType;
  92. //! @brief Register index if argument is passed through register, otherwise
  93. //! @c INVALID_VALUE.
  94. uint32_t registerIndex;
  95. //! @brief Stack offset if argument is passed through stack, otherwise
  96. //! @c INVALID_VALUE.
  97. int32_t stackOffset;
  98. //! @brief Get whether the argument is assigned, for private use only.
  99. inline bool isAssigned() const ASMJIT_NOTHROW
  100. { return registerIndex != INVALID_VALUE || stackOffset != (int32_t)INVALID_VALUE; }
  101. };
  102. // --------------------------------------------------------------------------
  103. // [Methods]
  104. // --------------------------------------------------------------------------
  105. //! @brief Set function prototype.
  106. //!
  107. //! This will set function calling convention and setup arguments variables.
  108. //!
  109. //! @note This function will allocate variables, it can be called only once.
  110. void setPrototype(
  111. uint32_t callingConvention,
  112. const uint32_t* arguments,
  113. uint32_t argumentsCount,
  114. uint32_t returnValue) ASMJIT_NOTHROW;
  115. //! @brief Get function calling convention, see @c CALL_CONV.
  116. inline uint32_t getCallingConvention() const ASMJIT_NOTHROW { return _callingConvention; }
  117. //! @brief Get whether the callee pops the stack.
  118. inline uint32_t getCalleePopsStack() const ASMJIT_NOTHROW { return _calleePopsStack; }
  119. //! @brief Get function arguments.
  120. inline Argument* getArguments() ASMJIT_NOTHROW { return _arguments; }
  121. //! @brief Get function arguments (const version).
  122. inline const Argument* getArguments() const ASMJIT_NOTHROW { return _arguments; }
  123. //! @brief Get count of arguments.
  124. inline uint32_t getArgumentsCount() const ASMJIT_NOTHROW { return _argumentsCount; }
  125. //! @brief Get function return value or @ref INVALID_VALUE if it's void.
  126. inline uint32_t getReturnValue() const ASMJIT_NOTHROW { return _returnValue; }
  127. //! @brief Get direction of arguments passed on the stack.
  128. //!
  129. //! Direction should be always @c ARGUMENT_DIR_RIGHT_TO_LEFT.
  130. //!
  131. //! @note This is related to used calling convention, it's not affected by
  132. //! number of function arguments or their types.
  133. inline uint32_t getArgumentsDirection() const ASMJIT_NOTHROW { return _argumentsDirection; }
  134. //! @brief Get stack size needed for function arguments passed on the stack.
  135. inline uint32_t getArgumentsStackSize() const ASMJIT_NOTHROW { return _argumentsStackSize; }
  136. //! @brief Get registers used to pass first integer parameters by current
  137. //! calling convention.
  138. //!
  139. //! @note This is related to used calling convention, it's not affected by
  140. //! number of function arguments or their types.
  141. inline const uint32_t* getArgumentsGPList() const ASMJIT_NOTHROW { return _argumentsGPList; }
  142. //! @brief Get registers used to pass first SP-FP or DP-FPparameters by
  143. //! current calling convention.
  144. //!
  145. //! @note This is related to used calling convention, it's not affected by
  146. //! number of function arguments or their types.
  147. inline const uint32_t* getArgumentsXMMList() const ASMJIT_NOTHROW { return _argumentsXMMList; }
  148. //! @brief Get bitmask of GP registers which might be used for arguments.
  149. inline uint32_t getArgumentsGP() const ASMJIT_NOTHROW { return _argumentsGP; }
  150. //! @brief Get bitmask of MM registers which might be used for arguments.
  151. inline uint32_t getArgumentsMM() const ASMJIT_NOTHROW { return _argumentsMM; }
  152. //! @brief Get bitmask of XMM registers which might be used for arguments.
  153. inline uint32_t getArgumentsXMM() const ASMJIT_NOTHROW { return _argumentsXMM; }
  154. //! @brief Get bitmask of general purpose registers that's preserved
  155. //! (non-volatile).
  156. //!
  157. //! @note This is related to used calling convention, it's not affected by
  158. //! number of function arguments or their types.
  159. inline uint32_t getPreservedGP() const ASMJIT_NOTHROW { return _preservedGP; }
  160. //! @brief Get bitmask of MM registers that's preserved (non-volatile).
  161. //!
  162. //! @note No standardized calling function is not preserving MM registers.
  163. //! This member is here for extension writers who need for some reason custom
  164. //! calling convention that can be called through code generated by AsmJit
  165. //! (or other runtime code generator).
  166. inline uint32_t getPreservedMM() const ASMJIT_NOTHROW { return _preservedMM; }
  167. //! @brief Return bitmask of XMM registers that's preserved (non-volatile).
  168. //!
  169. //! @note This is related to used calling convention, it's not affected by
  170. //! number of function arguments or their types.
  171. inline uint32_t getPreservedXMM() const ASMJIT_NOTHROW { return _preservedXMM; }
  172. //! @brief Get mask of all GP registers used to pass function arguments.
  173. inline uint32_t getPassedGP() const ASMJIT_NOTHROW { return _passedGP; }
  174. //! @brief Get mask of all MM registers used to pass function arguments.
  175. inline uint32_t getPassedMM() const ASMJIT_NOTHROW { return _passedMM; }
  176. //! @brief Get mask of all XMM registers used to pass function arguments.
  177. inline uint32_t getPassedXMM() const ASMJIT_NOTHROW { return _passedXMM; }
  178. //! @brief Find argument (id) by the register code. Used mainly by @ref ECall
  179. //! emittable.
  180. uint32_t findArgumentByRegisterCode(uint32_t regCode) const ASMJIT_NOTHROW;
  181. protected:
  182. // --------------------------------------------------------------------------
  183. // [Private]
  184. // --------------------------------------------------------------------------
  185. void _clear() ASMJIT_NOTHROW;
  186. void _setCallingConvention(uint32_t callingConvention) ASMJIT_NOTHROW;
  187. void _setPrototype(
  188. const uint32_t* arguments,
  189. uint32_t argumentsCount,
  190. uint32_t returnValue) ASMJIT_NOTHROW;
  191. void _setReturnValue(uint32_t valueId) ASMJIT_NOTHROW;
  192. // --------------------------------------------------------------------------
  193. // [Members]
  194. // --------------------------------------------------------------------------
  195. //! @brief Calling convention.
  196. uint32_t _callingConvention;
  197. //! @brief Whether callee pops stack.
  198. uint32_t _calleePopsStack;
  199. //! @brief List of arguments, their register codes or stack locations.
  200. Argument _arguments[FUNC_MAX_ARGS];
  201. //! @brief Function return value.
  202. uint32_t _returnValue;
  203. //! @brief Count of arguments (in @c _argumentsList).
  204. uint32_t _argumentsCount;
  205. //! @brief Direction for arguments passed on the stack, see @c ARGUMENT_DIR.
  206. uint32_t _argumentsDirection;
  207. //! @brief Count of bytes consumed by arguments on the stack.
  208. uint32_t _argumentsStackSize;
  209. //! @brief List of registers that's used for first GP arguments.
  210. uint32_t _argumentsGPList[16];
  211. //! @brief List of registers that's used for first XMM arguments.
  212. uint32_t _argumentsXMMList[16];
  213. //! @brief Bitmask for preserved GP registers.
  214. uint32_t _argumentsGP;
  215. //! @brief Bitmask for preserved MM registers.
  216. uint32_t _argumentsMM;
  217. //! @brief Bitmask for preserved XMM registers.
  218. uint32_t _argumentsXMM;
  219. //! @brief Bitmask for preserved GP registers.
  220. uint32_t _preservedGP;
  221. //! @brief Bitmask for preserved MM registers.
  222. uint32_t _preservedMM;
  223. //! @brief Bitmask for preserved XMM registers.
  224. uint32_t _preservedXMM;
  225. // Set by _setPrototype().
  226. //! @brief Bitmask for GP registers used as function arguments.
  227. uint32_t _passedGP;
  228. //! @brief Bitmask for GP registers used as function arguments.
  229. uint32_t _passedMM;
  230. //! @brief Bitmask for GP registers used as function arguments.
  231. uint32_t _passedXMM;
  232. };
  233. // ============================================================================
  234. // [AsmJit::VarData]
  235. // ============================================================================
  236. //! @brief Variable data (used internally by @c Compiler).
  237. struct VarData
  238. {
  239. // --------------------------------------------------------------------------
  240. // [Scope]
  241. // --------------------------------------------------------------------------
  242. //! @brief Scope (NULL if variable is global).
  243. EFunction* scope;
  244. //! @brief The first emittable where the variable is accessed.
  245. //!
  246. //! @note If this member is @c NULL then variable is unused.
  247. Emittable* firstEmittable;
  248. //! @brief The first callable (ECall) which is after the @c firstEmittable.
  249. ECall* firstCallable;
  250. //! @brief The last emittable where the variable is accessed.
  251. Emittable* lastEmittable;
  252. // --------------------------------------------------------------------------
  253. // [Id / Name]
  254. // --------------------------------------------------------------------------
  255. //! @brief Variable name.
  256. const char* name;
  257. //! @brief Variable id.
  258. uint32_t id;
  259. //! @brief Variable type.
  260. uint32_t type;
  261. //! @brief Variable size.
  262. uint32_t size;
  263. // --------------------------------------------------------------------------
  264. // [Home]
  265. // --------------------------------------------------------------------------
  266. //! @brief Home register index or @c INVALID_VALUE (used by register allocator).
  267. uint32_t homeRegisterIndex;
  268. //! @brief Preferred register index.
  269. uint32_t prefRegisterMask;
  270. //! @brief Home memory address offset.
  271. int32_t homeMemoryOffset;
  272. //! @brief Used by @c CompilerContext, do not touch (NULL when created).
  273. void* homeMemoryData;
  274. // --------------------------------------------------------------------------
  275. // [Actual]
  276. // --------------------------------------------------------------------------
  277. //! @brief Actual register index (connected with actual @c StateData).
  278. uint32_t registerIndex;
  279. //! @brief Actual working offset. This member is set before register allocator
  280. //! is called. If workOffset is same as CompilerContext::_currentOffset then
  281. //! this variable is probably used in next instruction and can't be spilled.
  282. uint32_t workOffset;
  283. //! @brief Next active variable in circular double-linked list.
  284. VarData* nextActive;
  285. //! @brief Previous active variable in circular double-linked list.
  286. VarData* prevActive;
  287. // --------------------------------------------------------------------------
  288. // [Flags]
  289. // --------------------------------------------------------------------------
  290. //! @brief Variable priority.
  291. uint8_t priority;
  292. //! @brief Whether variable content can be calculated by simple instruction
  293. //!
  294. //! This is used mainly by mmx or sse2 code and variable allocator will
  295. //! never reserve space for this variable. Calculated variables are for
  296. //! example all zeros, all ones, etc.
  297. uint8_t calculated;
  298. //! @brief Whether variable is argument passed through register.
  299. uint8_t isRegArgument;
  300. //! @brief Whether variable is argument passed through memory.
  301. uint8_t isMemArgument;
  302. //! @brief Variable state (connected with actual @c StateData).
  303. uint8_t state;
  304. //! @brief Whether variable was changed (connected with actual @c StateData).
  305. uint8_t changed;
  306. //! @brief Save on unuse (at end of the variable scope).
  307. uint8_t saveOnUnuse;
  308. // --------------------------------------------------------------------------
  309. // [Statistics]
  310. // --------------------------------------------------------------------------
  311. //! @brief Register read statistics (used by instructions where this variable needs
  312. //! to be read only).
  313. uint32_t registerReadCount;
  314. //! @brief Register write statistics (used by instructions where this variable needs
  315. //! to be write only).
  316. uint32_t registerWriteCount;
  317. //! @brief Register read+write statistics (used by instructions where this variable
  318. //! needs to be read and write).
  319. uint32_t registerRWCount;
  320. //! @brief Register GPB.LO statistics (for code generator).
  321. uint32_t registerGPBLoCount;
  322. //! @brief Register GPB.HI statistics (for code generator).
  323. uint32_t registerGPBHiCount;
  324. //! @brief Memory read statistics.
  325. uint32_t memoryReadCount;
  326. //! @brief Memory write statistics.
  327. uint32_t memoryWriteCount;
  328. //! @brief Memory read+write statistics.
  329. uint32_t memoryRWCount;
  330. // --------------------------------------------------------------------------
  331. // [Temporary]
  332. // --------------------------------------------------------------------------
  333. //! @brief Temporary data that can be used in prepare/translate stage.
  334. //!
  335. //! Initial value is NULL and each emittable/code that will use it must also
  336. //! clear it.
  337. //!
  338. //! This temporary data is designed to be used by algorithms that need to
  339. //! set some state into the variables, do something and then cleanup. See
  340. //! state-switch and function call.
  341. union
  342. {
  343. void* tempPtr;
  344. sysint_t tempInt;
  345. };
  346. };
  347. // ============================================================================
  348. // [AsmJit::VarMemBlock]
  349. // ============================================================================
  350. struct VarMemBlock
  351. {
  352. int32_t offset;
  353. uint32_t size;
  354. VarMemBlock* nextUsed;
  355. VarMemBlock* nextFree;
  356. };
  357. // ============================================================================
  358. // [AsmJit::VarAllocRecord]
  359. // ============================================================================
  360. //! @brief Variable alloc record (for each instruction that uses variables).
  361. //!
  362. //! Variable record contains pointer to variable data and register allocation
  363. //! flags. These flags are important to determine the best alloc instruction.
  364. struct VarAllocRecord
  365. {
  366. //! @brief Variable data (the structure owned by @c Compiler).
  367. VarData* vdata;
  368. //! @brief Variable alloc flags, see @c VARIABLE_ALLOC.
  369. uint32_t vflags;
  370. //! @brief Register mask (default is 0).
  371. uint32_t regMask;
  372. };
  373. // ============================================================================
  374. // [AsmJit::VarCallRecord]
  375. // ============================================================================
  376. //! @brief Variable call-fn record (for each callable that uses variables).
  377. //!
  378. //! This record contains variables that are used to call a function (using
  379. //! @c ECall emittable). Each variable contains the registers where it must
  380. //! be and registers where the value will be returned.
  381. struct VarCallRecord
  382. {
  383. //! @brief Variable data (the structure owned by @c Compiler).
  384. VarData* vdata;
  385. uint32_t flags;
  386. uint8_t inCount;
  387. uint8_t inDone;
  388. uint8_t outCount;
  389. uint8_t outDone;
  390. enum FLAGS
  391. {
  392. FLAG_IN_GP = 0x0001,
  393. FLAG_IN_MM = 0x0002,
  394. FLAG_IN_XMM = 0x0004,
  395. FLAG_IN_STACK = 0x0008,
  396. FLAG_OUT_EAX = 0x0010,
  397. FLAG_OUT_EDX = 0x0020,
  398. FLAG_OUT_ST0 = 0x0040,
  399. FLAG_OUT_ST1 = 0x0080,
  400. FLAG_OUT_MM0 = 0x0100,
  401. FLAG_OUT_XMM0 = 0x0400,
  402. FLAG_OUT_XMM1 = 0x0800,
  403. FLAG_IN_MEM_PTR = 0x1000,
  404. FLAG_CALL_OPERAND_REG = 0x2000,
  405. FLAG_CALL_OPERAND_MEM = 0x4000,
  406. FLAG_UNUSE_AFTER_USE = 0x8000
  407. };
  408. };
  409. // ============================================================================
  410. // [AsmJit::VarHintRecord]
  411. // ============================================================================
  412. struct VarHintRecord
  413. {
  414. VarData* vdata;
  415. uint32_t hint;
  416. };
  417. // ============================================================================
  418. // [AsmJit::StateData]
  419. // ============================================================================
  420. //! @brief State data.
  421. struct StateData
  422. {
  423. enum { NUM_REGS = 16 + 8 + 16 };
  424. inline void clear() ASMJIT_NOTHROW
  425. {
  426. memset(this, 0, sizeof(*this));
  427. }
  428. // --------------------------------------------------------------------------
  429. // [Members]
  430. // --------------------------------------------------------------------------
  431. union
  432. {
  433. //! @brief All allocated variables in one array.
  434. VarData* regs[NUM_REGS];
  435. struct
  436. {
  437. //! @brief Allocated GP registers.
  438. VarData* gp[16];
  439. //! @brief Allocated MM registers.
  440. VarData* mm[8];
  441. //! @brief Allocated XMM registers.
  442. VarData* xmm[16];
  443. };
  444. };
  445. //! @brief Used GP registers bitmask.
  446. uint32_t usedGP;
  447. //! @brief Used MM registers bitmask.
  448. uint32_t usedMM;
  449. //! @brief Used XMM registers bitmask.
  450. uint32_t usedXMM;
  451. //! @brief Changed GP registers bitmask.
  452. uint32_t changedGP;
  453. //! @brief Changed MM registers bitmask.
  454. uint32_t changedMM;
  455. //! @brief Changed XMM registers bitmask.
  456. uint32_t changedXMM;
  457. //! @brief Count of variables in @c memVarsData.
  458. uint32_t memVarsCount;
  459. //! @brief Variables stored in memory (@c VARIABLE_STATE_MEMORY).
  460. //!
  461. //! When saving / restoring state it's important to keep registers which are
  462. //! still in memory. Register is always unused when it is going out-of-scope.
  463. //! All variables which are not here are unused (@c VARIABLE_STATE_UNUSED).
  464. VarData* memVarsData[1];
  465. };
  466. // ============================================================================
  467. // [AsmJit::ForwardJumpData]
  468. // ============================================================================
  469. struct ForwardJumpData
  470. {
  471. EJmp* inst;
  472. StateData* state;
  473. ForwardJumpData* next;
  474. };
  475. // ============================================================================
  476. // [AsmJit::EVariableHint]
  477. // ============================================================================
  478. //! @brief Variable hint.
  479. struct ASMJIT_API EVariableHint : public Emittable
  480. {
  481. // --------------------------------------------------------------------------
  482. // [Construction / Destruction]
  483. // --------------------------------------------------------------------------
  484. //! @brief Create a new @ref EVariableHint instance.
  485. EVariableHint(Compiler* c, VarData* vdata, uint32_t hintId, uint32_t hintValue) ASMJIT_NOTHROW;
  486. //! @brief Destroy the @ref EVariableHInt instance.
  487. virtual ~EVariableHint() ASMJIT_NOTHROW;
  488. // --------------------------------------------------------------------------
  489. // [Emit]
  490. // --------------------------------------------------------------------------
  491. virtual void prepare(CompilerContext& cc) ASMJIT_NOTHROW;
  492. virtual Emittable* translate(CompilerContext& cc) ASMJIT_NOTHROW;
  493. // --------------------------------------------------------------------------
  494. // [Utilities]
  495. // --------------------------------------------------------------------------
  496. virtual int getMaxSize() const ASMJIT_NOTHROW;
  497. // --------------------------------------------------------------------------
  498. // [Hint]
  499. // --------------------------------------------------------------------------
  500. //! @brief Get assigned variable (data).
  501. inline VarData* getVar() const ASMJIT_NOTHROW { return _vdata; }
  502. //! @brief Get hint it (see @ref VARIABLE_HINT).
  503. inline uint32_t getHintId() const ASMJIT_NOTHROW { return _hintId; }
  504. //! @brief Get hint value.
  505. inline uint32_t getHintValue() const ASMJIT_NOTHROW { return _hintValue; }
  506. //! @brief Set hint it (see @ref VARIABLE_HINT).
  507. inline void setHintId(uint32_t hintId) ASMJIT_NOTHROW { _hintId = hintId; }
  508. //! @brief Set hint value.
  509. inline void setHintValue(uint32_t hintValue) ASMJIT_NOTHROW { _hintValue = hintValue; }
  510. VarData* _vdata;
  511. uint32_t _hintId;
  512. uint32_t _hintValue;
  513. };
  514. // ============================================================================
  515. // [AsmJit::EInstruction]
  516. // ============================================================================
  517. //! @brief Emittable that represents single instruction and its operands.
  518. struct ASMJIT_API EInstruction : public Emittable
  519. {
  520. // --------------------------------------------------------------------------
  521. // [Construction / Destruction]
  522. // --------------------------------------------------------------------------
  523. //! @brief Create a new @ref EInstruction instance.
  524. EInstruction(Compiler* c, uint32_t code, Operand* operandsData, uint32_t operandsCount) ASMJIT_NOTHROW;
  525. //! @brief Destroy the @ref EInstruction instance.
  526. virtual ~EInstruction() ASMJIT_NOTHROW;
  527. // --------------------------------------------------------------------------
  528. // [Emit]
  529. // --------------------------------------------------------------------------
  530. virtual void prepare(CompilerContext& cc) ASMJIT_NOTHROW;
  531. virtual Emittable* translate(CompilerContext& cc) ASMJIT_NOTHROW;
  532. virtual void emit(Assembler& a) ASMJIT_NOTHROW;
  533. // --------------------------------------------------------------------------
  534. // [Utilities]
  535. // --------------------------------------------------------------------------
  536. virtual int getMaxSize() const ASMJIT_NOTHROW;
  537. virtual bool _tryUnuseVar(VarData* v) ASMJIT_NOTHROW;
  538. // --------------------------------------------------------------------------
  539. // [Instruction Code]
  540. // --------------------------------------------------------------------------
  541. //! @brief Get whether the instruction is special.
  542. inline bool isSpecial() const ASMJIT_NOTHROW { return _isSpecial; }
  543. //! @brief Get whether the instruction is FPU.
  544. inline bool isFPU() const ASMJIT_NOTHROW { return _isFPU; }
  545. //! @brief Get instruction code, see @c INST_CODE.
  546. inline uint32_t getCode() const ASMJIT_NOTHROW { return _code; }
  547. //! @brief Set instruction code to @a code.
  548. //!
  549. //! Please do not modify instruction code if you are not know what you are
  550. //! doing. Incorrect instruction code or operands can raise assertion() at
  551. //! runtime.
  552. inline void setCode(uint32_t code) ASMJIT_NOTHROW { _code = code; }
  553. // --------------------------------------------------------------------------
  554. // [Operands]
  555. // --------------------------------------------------------------------------
  556. //! @brief Get count of operands in operands array (number between 0 to 2 inclusive).
  557. inline uint32_t getOperandsCount() const ASMJIT_NOTHROW { return _operandsCount; }
  558. //! @brief Get operands array (3 operands total).
  559. inline Operand* getOperands() ASMJIT_NOTHROW { return _operands; }
  560. //! @brief Get operands array (3 operands total).
  561. inline const Operand* getOperands() const ASMJIT_NOTHROW { return _operands; }
  562. //! @brief Get memory operand.
  563. inline Mem* getMemOp() ASMJIT_NOTHROW { return _memOp; }
  564. //! @brief Set memory operand.
  565. inline void setMemOp(Mem* op) ASMJIT_NOTHROW { _memOp = op; }
  566. // --------------------------------------------------------------------------
  567. // [Variables]
  568. // --------------------------------------------------------------------------
  569. //! @brief Get count of variables in instruction operands (and in variables array).
  570. inline uint32_t getVariablesCount() const ASMJIT_NOTHROW { return _variablesCount; }
  571. //! @brief Get operands array (3 operands total).
  572. inline VarAllocRecord* getVariables() ASMJIT_NOTHROW { return _variables; }
  573. //! @brief Get operands array (3 operands total).
  574. inline const VarAllocRecord* getVariables() const ASMJIT_NOTHROW { return _variables; }
  575. // --------------------------------------------------------------------------
  576. // [Jump]
  577. // --------------------------------------------------------------------------
  578. //! @brief Get possible jump target.
  579. //!
  580. //! If this instruction is conditional or normal jump then return value is
  581. //! label location (ETarget instance), otherwise return value is @c NULL.
  582. virtual ETarget* getJumpTarget() const ASMJIT_NOTHROW;
  583. // --------------------------------------------------------------------------
  584. // [Members]
  585. // --------------------------------------------------------------------------
  586. protected:
  587. //! @brief Instruction code, see @c INST_CODE.
  588. uint32_t _code;
  589. //! @brief Emit options, see @c EMIT_OPTIONS.
  590. uint32_t _emitOptions;
  591. //! @brief Operands count.
  592. uint32_t _operandsCount;
  593. //! @brief Variables count.
  594. uint32_t _variablesCount;
  595. //! @brief Operands.
  596. Operand* _operands;
  597. //! @brief Memory operand (if instruction contains any).
  598. Mem* _memOp;
  599. //! @brief Variables (extracted from operands).
  600. VarAllocRecord* _variables;
  601. //! @brief Whether the instruction is special.
  602. bool _isSpecial;
  603. //! @brief Whether the instruction is FPU.
  604. bool _isFPU;
  605. //! @brief Whether the one of the operands is GPB.Lo register.
  606. bool _isGPBLoUsed;
  607. //! @brief Whether the one of the operands is GPB.Hi register.
  608. bool _isGPBHiUsed;
  609. friend struct EFunction;
  610. friend struct CompilerContext;
  611. friend struct CompilerCore;
  612. private:
  613. ASMJIT_DISABLE_COPY(EInstruction)
  614. };
  615. // ============================================================================
  616. // [AsmJit::EJmp]
  617. // ============================================================================
  618. //! @brief Emittable that represents single instruction that can jump somewhere.
  619. struct ASMJIT_API EJmp : public EInstruction
  620. {
  621. // --------------------------------------------------------------------------
  622. // [Construction / Destruction]
  623. // --------------------------------------------------------------------------
  624. EJmp(Compiler* c, uint32_t code, Operand* operandsData, uint32_t operandsCount) ASMJIT_NOTHROW;
  625. virtual ~EJmp() ASMJIT_NOTHROW;
  626. // --------------------------------------------------------------------------
  627. // [Emit]
  628. // --------------------------------------------------------------------------
  629. virtual void prepare(CompilerContext& cc) ASMJIT_NOTHROW;
  630. virtual Emittable* translate(CompilerContext& cc) ASMJIT_NOTHROW;
  631. virtual void emit(Assembler& a) ASMJIT_NOTHROW;
  632. void _doJump(CompilerContext& cc) ASMJIT_NOTHROW;
  633. // --------------------------------------------------------------------------
  634. // [Jump]
  635. // --------------------------------------------------------------------------
  636. virtual ETarget* getJumpTarget() const ASMJIT_NOTHROW;
  637. inline EJmp* getJumpNext() const ASMJIT_NOTHROW { return _jumpNext; }
  638. inline bool isTaken() const ASMJIT_NOTHROW { return _isTaken; }
  639. // --------------------------------------------------------------------------
  640. // [Members]
  641. // --------------------------------------------------------------------------
  642. protected:
  643. ETarget* _jumpTarget;
  644. EJmp *_jumpNext;
  645. StateData* _state;
  646. bool _isTaken;
  647. friend struct EFunction;
  648. friend struct CompilerContext;
  649. friend struct CompilerCore;
  650. private:
  651. ASMJIT_DISABLE_COPY(EJmp)
  652. };
  653. // ============================================================================
  654. // [AsmJit::EFunction]
  655. // ============================================================================
  656. //! @brief Function emittable used to generate C/C++ functions.
  657. //!
  658. //! Functions are base blocks for generating assembler output. Each generated
  659. //! assembler stream needs standard entry and leave sequences thats compatible
  660. //! to the operating system conventions - Application Binary Interface (ABI).
  661. //!
  662. //! Function class can be used to generate entry (prolog) and leave (epilog)
  663. //! sequences that is compatible to a given calling convention and to allocate
  664. //! and manage variables that can be allocated to registers or spilled.
  665. //!
  666. //! @note To create function use @c AsmJit::Compiler::newFunction() method, do
  667. //! not create @c EFunction instances using other ways.
  668. //!
  669. //! @sa @c State, @c Var.
  670. struct ASMJIT_API EFunction : public Emittable
  671. {
  672. // --------------------------------------------------------------------------
  673. // [Construction / Destruction]
  674. // --------------------------------------------------------------------------
  675. //! @brief Create new @c Function instance.
  676. //!
  677. //! @note Always use @c AsmJit::Compiler::newFunction() to create @c Function
  678. //! instance.
  679. EFunction(Compiler* c) ASMJIT_NOTHROW;
  680. //! @brief Destroy @c Function instance.
  681. virtual ~EFunction() ASMJIT_NOTHROW;
  682. // --------------------------------------------------------------------------
  683. // [Emit]
  684. // --------------------------------------------------------------------------
  685. virtual void prepare(CompilerContext& cc) ASMJIT_NOTHROW;
  686. // --------------------------------------------------------------------------
  687. // [Utilities]
  688. // --------------------------------------------------------------------------
  689. virtual int getMaxSize() const ASMJIT_NOTHROW;
  690. // --------------------------------------------------------------------------
  691. // [Function Prototype (Calling Convention + Arguments) / Return Value]
  692. // --------------------------------------------------------------------------
  693. inline const FunctionPrototype& getPrototype() const ASMJIT_NOTHROW { return _functionPrototype; }
  694. inline uint32_t getHint(uint32_t hint) ASMJIT_NOTHROW { return _hints[hint]; }
  695. void setPrototype(
  696. uint32_t callingConvention,
  697. const uint32_t* arguments,
  698. uint32_t argumentsCount,
  699. uint32_t returnValue) ASMJIT_NOTHROW;
  700. void setHint(uint32_t hint, uint32_t value) ASMJIT_NOTHROW;
  701. inline EProlog* getProlog() const ASMJIT_NOTHROW { return _prolog; }
  702. inline EEpilog* getEpilog() const ASMJIT_NOTHROW { return _epilog; }
  703. inline EFunctionEnd* getEnd() const ASMJIT_NOTHROW { return _end; }
  704. //! @brief Create variables from FunctionPrototype declaration. This is just
  705. //! parsing what FunctionPrototype generated for current function calling
  706. //! convention and arguments.
  707. void _createVariables() ASMJIT_NOTHROW;
  708. //! @brief Prepare variables (ids, names, scope, registers).
  709. void _prepareVariables(Emittable* first) ASMJIT_NOTHROW;
  710. //! @brief Allocate variables (setting correct state, changing masks, etc).
  711. void _allocVariables(CompilerContext& cc) ASMJIT_NOTHROW;
  712. void _preparePrologEpilog(CompilerContext& cc) ASMJIT_NOTHROW;
  713. void _dumpFunction(CompilerContext& cc) ASMJIT_NOTHROW;
  714. void _emitProlog(CompilerContext& cc) ASMJIT_NOTHROW;
  715. void _emitEpilog(CompilerContext& cc) ASMJIT_NOTHROW;
  716. // --------------------------------------------------------------------------
  717. // [Function-Call]
  718. // --------------------------------------------------------------------------
  719. //! @brief Reserve stack for calling other function and mark function as
  720. //! callee.
  721. void reserveStackForFunctionCall(int32_t size);
  722. // --------------------------------------------------------------------------
  723. // [Labels]
  724. // --------------------------------------------------------------------------
  725. //! @brief Get function entry label.
  726. //!
  727. //! Entry label can be used to call this function from another code that's
  728. //! being generated.
  729. inline const Label& getEntryLabel() const ASMJIT_NOTHROW { return _entryLabel; }
  730. //! @brief Get function exit label.
  731. //!
  732. //! Use exit label to jump to function epilog.
  733. inline const Label& getExitLabel() const ASMJIT_NOTHROW { return _exitLabel; }
  734. // --------------------------------------------------------------------------
  735. // [Misc]
  736. // --------------------------------------------------------------------------
  737. //! @brief Set the _isEspAdjusted member to true.
  738. //!
  739. //! This method is used to tell compiler that the ESP/RSP must be adjusted in
  740. //! function prolog/epilog, because the stack is manipulated (usually caused
  741. //! by the function call, see @c ECall).
  742. inline void mustAdjustEsp() { _isEspAdjusted = true; }
  743. // --------------------------------------------------------------------------
  744. // [Members]
  745. // --------------------------------------------------------------------------
  746. protected:
  747. //! @brief Function prototype.
  748. FunctionPrototype _functionPrototype;
  749. //! @brief Function arguments (variable IDs).
  750. VarData** _argumentVariables;
  751. //! @brief Function hints.
  752. uint32_t _hints[16];
  753. //! @brief Whether the function stack is aligned by 16-bytes by OS.
  754. //!
  755. //! This is always true for 64-bit mode and for linux.
  756. bool _isStackAlignedByOsTo16Bytes;
  757. //! @brief Whether the function stack (for variables) is aligned manually
  758. //! by function to 16-bytes.
  759. //!
  760. //! This makes sense only if _isStackAlignedByOsTo16Bytes is false and MOVDQA
  761. //! instruction or other SSE/SSE2 instructions are used to work with variable
  762. //! stored on the stack.
  763. //!
  764. //! Value is determined automatically by these factors, expectations are:
  765. //!
  766. //! 1. There is 16-byte wide variable which address was used (alloc, spill,
  767. //! op).
  768. //! 2. Function can't be naked.
  769. bool _isStackAlignedByFnTo16Bytes;
  770. //! @brief Whether the function is using naked prolog / epilog
  771. //!
  772. //! Naked prolog / epilog means to omit saving and restoring EBP.
  773. bool _isNaked;
  774. //! @brief Whether the ESP register is adjusted by the stack size needed
  775. //! to save registers and function variables.
  776. //!
  777. //! Esp is adjusted by 'sub' instruction in prolog and by add function in
  778. //! epilog (only if function is not naked).
  779. bool _isEspAdjusted;
  780. //! @brief Whether another function is called from this function.
  781. //!
  782. //! If another function is called from this function, it's needed to prepare
  783. //! stack for it. If this member is true then it's likely that true will be
  784. //! also @c _isEspAdjusted one.
  785. bool _isCaller;
  786. //! @brief Whether to emit prolog / epilog sequence using push & pop
  787. //! instructions (the default).
  788. bool _pePushPop;
  789. //! @brief Whether to emit EMMS instruction in epilog (auto-detected).
  790. bool _emitEMMS;
  791. //! @brief Whether to emit SFence instruction in epilog (auto-detected).
  792. //!
  793. //! @note Combination of @c _emitSFence and @c _emitLFence will result in
  794. //! emitting mfence.
  795. bool _emitSFence;
  796. //! @brief Whether to emit LFence instruction in epilog (auto-detected).
  797. //!
  798. //! @note Combination of @c _emitSFence and @c _emitLFence will result in
  799. //! emitting mfence.
  800. bool _emitLFence;
  801. //! @brief Whether the function is finished using @c Compiler::endFunction().
  802. bool _finished;
  803. //! @brief Bitfield containing modified and preserved GP registers.
  804. uint32_t _modifiedAndPreservedGP;
  805. //! @brief Bitfield containing modified and preserved MM registers.
  806. uint32_t _modifiedAndPreservedMM;
  807. //! @brief Bitfield containing modified and preserved XMM registers.
  808. uint32_t _modifiedAndPreservedXMM;
  809. //! @brief ID mov movdqa instruction (@c INST_MOVDQA or @c INST_MOVDQU).
  810. //!
  811. //! The value is based on stack alignment. If it's guaranteed that stack
  812. //! is aligned to 16-bytes then @c INST_MOVDQA instruction is used, otherwise
  813. //! the @c INST_MOVDQU instruction is used for 16-byte mov.
  814. uint32_t _movDqaInstruction;
  815. //! @brief Prolog / epilog stack size for PUSH/POP sequences.
  816. int32_t _pePushPopStackSize;
  817. //! @brief Prolog / epilog stack size for MOV sequences.
  818. int32_t _peMovStackSize;
  819. //! @brief Prolog / epilog stack adjust size (to make it 16-byte aligned).
  820. int32_t _peAdjustStackSize;
  821. //! @brief Memory stack size (for all variables and temporary memory).
  822. int32_t _memStackSize;
  823. //! @brief Like @c _memStackSize, but aligned to 16-bytes.
  824. int32_t _memStackSize16;
  825. //! @brief Stack size needed to call other functions.
  826. int32_t _functionCallStackSize;
  827. //! @brief Function entry label.
  828. Label _entryLabel;
  829. //! @brief Function exit label.
  830. Label _exitLabel;
  831. //! @brief Function prolog emittable.
  832. EProlog* _prolog;
  833. //! @brief Function epilog emittable.
  834. EEpilog* _epilog;
  835. //! @brief Dummy emittable, signalizes end of function.
  836. EFunctionEnd* _end;
  837. private:
  838. friend struct CompilerContext;
  839. friend struct CompilerCore;
  840. friend struct EProlog;
  841. friend struct EEpilog;
  842. };
  843. // ============================================================================
  844. // [AsmJit::EProlog]
  845. // ============================================================================
  846. //! @brief Prolog emittable.
  847. struct ASMJIT_API EProlog : public Emittable
  848. {
  849. // --------------------------------------------------------------------------
  850. // [Construction / Destruction]
  851. // --------------------------------------------------------------------------
  852. //! @brief Create a new @ref EProlog instance.
  853. EProlog(Compiler* c, EFunction* f) ASMJIT_NOTHROW;
  854. //! @brief Destroy the @ref EProlog instance.
  855. virtual ~EProlog() ASMJIT_NOTHROW;
  856. // --------------------------------------------------------------------------
  857. // [Emit]
  858. // --------------------------------------------------------------------------
  859. virtual void prepare(CompilerContext& cc) ASMJIT_NOTHROW;
  860. virtual Emittable* translate(CompilerContext& cc) ASMJIT_NOTHROW;
  861. // --------------------------------------------------------------------------
  862. // [Methods]
  863. // --------------------------------------------------------------------------
  864. //! @brief Get function associated with this prolog.
  865. inline EFunction* getFunction() const ASMJIT_NOTHROW { return _function; }
  866. // --------------------------------------------------------------------------
  867. // [Members]
  868. // --------------------------------------------------------------------------
  869. protected:
  870. //! @brief Prolog owner function.
  871. EFunction* _function;
  872. private:
  873. friend struct CompilerCore;
  874. friend struct EFunction;
  875. };
  876. // ============================================================================
  877. // [AsmJit::EEpilog]
  878. // ============================================================================
  879. //! @brief Epilog emittable.
  880. struct ASMJIT_API EEpilog : public Emittable
  881. {
  882. // --------------------------------------------------------------------------
  883. // [Construction / Destruction]
  884. // --------------------------------------------------------------------------
  885. //! @brief Create a new @ref EEpilog instance.
  886. EEpilog(Compiler* c, EFunction* f) ASMJIT_NOTHROW;
  887. //! @brief Destroy the @ref EProlog instance.
  888. virtual ~EEpilog() ASMJIT_NOTHROW;
  889. // --------------------------------------------------------------------------
  890. // [Emit]
  891. // --------------------------------------------------------------------------
  892. virtual void prepare(CompilerContext& cc) ASMJIT_NOTHROW;
  893. virtual Emittable* translate(CompilerContext& cc) ASMJIT_NOTHROW;
  894. // --------------------------------------------------------------------------
  895. // [Methods]
  896. // --------------------------------------------------------------------------
  897. //! @brief Get function associated with this epilog.
  898. inline EFunction* getFunction() const ASMJIT_NOTHROW { return _function; }
  899. // --------------------------------------------------------------------------
  900. // [Members]
  901. // --------------------------------------------------------------------------
  902. protected:
  903. //! @brief Epilog owner function.
  904. EFunction* _function;
  905. private:
  906. friend struct CompilerCore;
  907. friend struct EFunction;
  908. };
  909. // ============================================================================
  910. // [AsmJit::ECall]
  911. // ============================================================================
  912. //! @brief Function call.
  913. struct ASMJIT_API ECall : public Emittable
  914. {
  915. // --------------------------------------------------------------------------
  916. // [Construction / Destruction]
  917. // --------------------------------------------------------------------------
  918. //! @brief Create a new @ref ECall instance.
  919. ECall(Compiler* c, EFunction* caller, const Operand* target) ASMJIT_NOTHROW;
  920. //! @brief Destroy the @ref ECall instance.
  921. virtual ~ECall() ASMJIT_NOTHROW;
  922. // --------------------------------------------------------------------------
  923. // [Emit]
  924. // --------------------------------------------------------------------------
  925. virtual void prepare(CompilerContext& cc) ASMJIT_NOTHROW;
  926. virtual Emittable* translate(CompilerContext& cc) ASMJIT_NOTHROW;
  927. // --------------------------------------------------------------------------
  928. // [Utilities]
  929. // --------------------------------------------------------------------------
  930. virtual int getMaxSize() const ASMJIT_NOTHROW;
  931. virtual bool _tryUnuseVar(VarData* v) ASMJIT_NOTHROW;
  932. // --------------------------------------------------------------------------
  933. // [Internal]
  934. // --------------------------------------------------------------------------
  935. protected:
  936. uint32_t _findTemporaryGpRegister(CompilerContext& cc) ASMJIT_NOTHROW;
  937. uint32_t _findTemporaryXmmRegister(CompilerContext& cc) ASMJIT_NOTHROW;
  938. VarData* _getOverlappingVariable(CompilerContext& cc,
  939. const FunctionPrototype::Argument& argType) const ASMJIT_NOTHROW;
  940. void _moveAllocatedVariableToStack(CompilerContext& cc,
  941. VarData* vdata, const FunctionPrototype::Argument& argType) ASMJIT_NOTHROW;
  942. void _moveSpilledVariableToStack(CompilerContext& cc,
  943. VarData* vdata, const FunctionPrototype::Argument& argType,
  944. uint32_t temporaryGpReg,
  945. uint32_t temporaryXmmReg) ASMJIT_NOTHROW;
  946. void _moveSrcVariableToRegister(CompilerContext& cc,
  947. VarData* vdata, const FunctionPrototype::Argument& argType) ASMJIT_NOTHROW;
  948. // --------------------------------------------------------------------------
  949. // [Function Prototype (Calling Convention + Arguments) / Return Value]
  950. // --------------------------------------------------------------------------
  951. public:
  952. //! @brief Get function prototype.
  953. inline const FunctionPrototype& getPrototype() const ASMJIT_NOTHROW { return _functionPrototype; }
  954. //! @brief Set function prototype.
  955. inline void setPrototype(uint32_t cconv, const FunctionDefinition& def) ASMJIT_NOTHROW
  956. {
  957. _setPrototype(
  958. cconv,
  959. def.getArguments(),
  960. def.getArgumentsCount(),
  961. def.getReturnValue());
  962. }
  963. //! @brief Set function prototype (internal).
  964. void _setPrototype(
  965. uint32_t callingConvention,
  966. const uint32_t* arguments,
  967. uint32_t argumentsCount,
  968. uint32_t returnValue) ASMJIT_NOTHROW;
  969. //! @brief Set function argument @a i to @a var.
  970. bool setArgument(uint32_t i, const BaseVar& var) ASMJIT_NOTHROW;
  971. //! @brief Set function argument @a i to @a imm.
  972. bool setArgument(uint32_t i, const Imm& imm) ASMJIT_NOTHROW;
  973. //! @brief Set return value to
  974. bool setReturn(const Operand& first, const Operand& second = Operand()) ASMJIT_NOTHROW;
  975. // --------------------------------------------------------------------------
  976. // [Methods]
  977. // --------------------------------------------------------------------------
  978. //! @brief Get caller.
  979. inline EFunction* getCaller() const ASMJIT_NOTHROW { return _caller; }
  980. //! @brief Get operand (function address).
  981. inline Operand& getTarget() ASMJIT_NOTHROW { return _target; }
  982. //! @overload
  983. inline const Operand& getTarget() const ASMJIT_NOTHROW { return _target; }
  984. // --------------------------------------------------------------------------
  985. // [Members]
  986. // --------------------------------------------------------------------------
  987. protected:
  988. //! @brief Function prototype.
  989. FunctionPrototype _functionPrototype;
  990. //! @brief Callee (the function that calls me).
  991. EFunction* _caller;
  992. //! @brief Arguments (operands).
  993. Operand* _args;
  994. //! @brief Operand (address of function, register, label, ...)
  995. Operand _target;
  996. //! @brief Return value (operands)
  997. Operand _ret[2];
  998. //! @brief Mask of GP registers used as function arguments.
  999. uint32_t _gpParams;
  1000. //! @brief Mask of MM registers used as function arguments.
  1001. uint32_t _mmParams;
  1002. //! @brief Mask of XMM registers used as function arguments.
  1003. uint32_t _xmmParams;
  1004. //! @brief Variables count.
  1005. uint32_t _variablesCount;
  1006. //! @brief Variables (extracted from operands).
  1007. VarCallRecord* _variables;
  1008. //! @brief Argument index to @c VarCallRecord.
  1009. VarCallRecord* _argumentToVarRecord[FUNC_MAX_ARGS];
  1010. private:
  1011. friend struct CompilerCore;
  1012. };
  1013. // ============================================================================
  1014. // [AsmJit::ERet]
  1015. // ============================================================================
  1016. //! @brief Function return.
  1017. struct ASMJIT_API ERet : public Emittable
  1018. {
  1019. // --------------------------------------------------------------------------
  1020. // [Construction / Destruction]
  1021. // --------------------------------------------------------------------------
  1022. //! @brief Create a new @ref ERet instance.
  1023. ERet(Compiler* c, EFunction* function, const Operand* first, const Operand* second) ASMJIT_NOTHROW;
  1024. //! @brief Destroy the @ref ERet instance.
  1025. virtual ~ERet() ASMJIT_NOTHROW;
  1026. // --------------------------------------------------------------------------
  1027. // [Emit]
  1028. // --------------------------------------------------------------------------
  1029. virtual void prepare(CompilerContext& cc) ASMJIT_NOTHROW;
  1030. virtual Emittable* translate(CompilerContext& cc) ASMJIT_NOTHROW;
  1031. virtual void emit(Assembler& a) ASMJIT_NOTHROW;
  1032. // --------------------------------------------------------------------------
  1033. // [Utilities]
  1034. // --------------------------------------------------------------------------
  1035. virtual int getMaxSize() const ASMJIT_NOTHROW;
  1036. // --------------------------------------------------------------------------
  1037. // [Methods]
  1038. // --------------------------------------------------------------------------
  1039. //! @Brief Get function.
  1040. inline EFunction* getFunction() ASMJIT_NOTHROW { return _function; }
  1041. //! @brief Get operand (function address).
  1042. inline Operand& getFirst() ASMJIT_NOTHROW { return _ret[0]; }
  1043. //! @brief Get operand (function address).
  1044. inline Operand& getSecond() ASMJIT_NOTHROW { return _ret[1]; }
  1045. //! @overload
  1046. inline const Operand& getFirst() const ASMJIT_NOTHROW { return _ret[0]; }
  1047. //! @overload
  1048. inline const Operand& getSecond() const ASMJIT_NOTHROW { return _ret[1]; }
  1049. //! @brief Get whether jump to epilog have to be emitted.
  1050. bool shouldEmitJumpToEpilog() const ASMJIT_NOTHROW;
  1051. // --------------------------------------------------------------------------
  1052. // [Members]
  1053. // --------------------------------------------------------------------------
  1054. protected:
  1055. //! @brief Function.
  1056. EFunction* _function;
  1057. //! @brief Return value (operands)
  1058. Operand _ret[2];
  1059. private:
  1060. friend struct CompilerCore;
  1061. };
  1062. // ============================================================================
  1063. // [AsmJit::CompilerContext]
  1064. // ============================================================================
  1065. //! @internal
  1066. //!
  1067. //! @brief Compiler context is used by @ref Compiler.
  1068. //!
  1069. //! Compiler context is used during compilation and normally developer doesn't
  1070. //! need access to it. The context is user per function (it's reset after each
  1071. //! function is generated).
  1072. struct ASMJIT_API CompilerContext
  1073. {
  1074. // --------------------------------------------------------------------------
  1075. // [Construction / Destruction]
  1076. // --------------------------------------------------------------------------
  1077. //! @brief Create a new @ref CompilerContext instanc…