operand.h 53 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316
  1. // [AsmJit]
  2. // Machine Code Generation for C++.
  3. //
  4. // [License]
  5. // Zlib - See LICENSE.md file in the package.
  6. #ifndef _ASMJIT_CORE_OPERAND_H
  7. #define _ASMJIT_CORE_OPERAND_H
  8. #include "../core/support.h"
  9. ASMJIT_BEGIN_NAMESPACE
  10. // ============================================================================
  11. // [Macros]
  12. // ============================================================================
  13. //! Adds a template specialization for `REG_TYPE` into the local `RegTraits`.
  14. #define ASMJIT_DEFINE_REG_TRAITS(REG, REG_TYPE, GROUP, SIZE, COUNT, TYPE_ID) \
  15. template<> \
  16. struct RegTraits<REG_TYPE> { \
  17. typedef REG RegT; \
  18. \
  19. static constexpr uint32_t kValid = 1; \
  20. static constexpr uint32_t kCount = COUNT; \
  21. static constexpr uint32_t kTypeId = TYPE_ID; \
  22. \
  23. static constexpr uint32_t kType = REG_TYPE; \
  24. static constexpr uint32_t kGroup = GROUP; \
  25. static constexpr uint32_t kSize = SIZE; \
  26. \
  27. static constexpr uint32_t kSignature = \
  28. (Operand::kOpReg << Operand::kSignatureOpShift ) | \
  29. (kType << Operand::kSignatureRegTypeShift ) | \
  30. (kGroup << Operand::kSignatureRegGroupShift) | \
  31. (kSize << Operand::kSignatureSizeShift ) ; \
  32. }
  33. //! Adds constructors and member functions to a class that implements abstract
  34. //! register. Abstract register is register that doesn't have type or signature
  35. //! yet, it's a base class like `x86::Reg` or `arm::Reg`.
  36. #define ASMJIT_DEFINE_ABSTRACT_REG(REG, BASE) \
  37. public: \
  38. /*! Default constructor that only setups basics. */ \
  39. constexpr REG() noexcept \
  40. : BASE(kSignature, kIdBad) {} \
  41. \
  42. /*! Makes a copy of the `other` register operand. */ \
  43. constexpr REG(const REG& other) noexcept \
  44. : BASE(other) {} \
  45. \
  46. /*! Makes a copy of the `other` register having id set to `rId` */ \
  47. constexpr REG(const BaseReg& other, uint32_t rId) noexcept \
  48. : BASE(other, rId) {} \
  49. \
  50. /*! Creates a register based on `signature` and `rId`. */ \
  51. constexpr REG(uint32_t signature, uint32_t rId) noexcept \
  52. : BASE(signature, rId) {} \
  53. \
  54. /*! Creates a completely uninitialized REG register operand (garbage). */ \
  55. inline explicit REG(Globals::NoInit_) noexcept \
  56. : BASE(Globals::NoInit) {} \
  57. \
  58. /*! Creates a new register from register type and id. */ \
  59. static inline REG fromTypeAndId(uint32_t rType, uint32_t rId) noexcept { \
  60. return REG(signatureOf(rType), rId); \
  61. } \
  62. \
  63. /*! Clones the register operand. */ \
  64. constexpr REG clone() const noexcept { return REG(*this); } \
  65. \
  66. inline REG& operator=(const REG& other) noexcept = default;
  67. //! Adds constructors and member functions to a class that implements final
  68. //! register. Final registers MUST HAVE a valid signature.
  69. #define ASMJIT_DEFINE_FINAL_REG(REG, BASE, TRAITS) \
  70. public: \
  71. static constexpr uint32_t kThisType = TRAITS::kType; \
  72. static constexpr uint32_t kThisGroup = TRAITS::kGroup; \
  73. static constexpr uint32_t kThisSize = TRAITS::kSize; \
  74. static constexpr uint32_t kSignature = TRAITS::kSignature; \
  75. \
  76. ASMJIT_DEFINE_ABSTRACT_REG(REG, BASE) \
  77. \
  78. /*! Creates a register operand having its id set to `rId`. */ \
  79. constexpr explicit REG(uint32_t rId) noexcept \
  80. : BASE(kSignature, rId) {}
  81. //! \addtogroup asmjit_core
  82. //! \{
  83. // ============================================================================
  84. // [asmjit::Operand_]
  85. // ============================================================================
  86. //! Constructor-less `Operand`.
  87. //!
  88. //! Contains no initialization code and can be used safely to define an array
  89. //! of operands that won't be initialized. This is an `Operand` compatible
  90. //! data structure designed to be statically initialized, static const, or to
  91. //! be used by the user to define an array of operands without having them
  92. //! default initialized.
  93. //!
  94. //! The key difference between `Operand` and `Operand_`:
  95. //!
  96. //! ```
  97. //! Operand_ xArray[10]; // Not initialized, contains garbage.
  98. //! Operand yArray[10]; // All operands initialized to none.
  99. //! ```
  100. struct Operand_ {
  101. //! Operand's signature that provides operand type and additional information.
  102. uint32_t _signature;
  103. //! Either base id as used by memory operand or any id as used by others.
  104. uint32_t _baseId;
  105. //! Memory operand data.
  106. struct MemData {
  107. //! Index register id.
  108. uint32_t indexId;
  109. //! Low part of 64-bit offset (or 32-bit offset).
  110. uint32_t offsetLo32;
  111. };
  112. //! Additional data used by some operands.
  113. union {
  114. //! 32-bit data (used either by immediate or as a 32-bit view).
  115. uint32_t _data32[2];
  116. //! 64-bit data (used either by immediate or as a 64-bit view).
  117. uint64_t _data64;
  118. //! Memory address data.
  119. MemData _mem;
  120. };
  121. //! Operand types that can be encoded in `Operand`.
  122. enum OpType : uint32_t {
  123. //! Not an operand or not initialized.
  124. kOpNone = 0,
  125. //! Operand is a register.
  126. kOpReg = 1,
  127. //! Operand is a memory.
  128. kOpMem = 2,
  129. //! Operand is an immediate value.
  130. kOpImm = 3,
  131. //! Operand is a label.
  132. kOpLabel = 4
  133. };
  134. static_assert(kOpMem == kOpReg + 1, "asmjit::Operand requires `kOpMem` to be `kOpReg+1`.");
  135. // \cond INTERNAL
  136. enum SignatureBits : uint32_t {
  137. // Operand type (3 least significant bits).
  138. // |........|........|........|.....XXX|
  139. kSignatureOpShift = 0,
  140. kSignatureOpMask = 0x07u << kSignatureOpShift,
  141. // Register type (5 bits).
  142. // |........|........|........|XXXXX...|
  143. kSignatureRegTypeShift = 3,
  144. kSignatureRegTypeMask = 0x1Fu << kSignatureRegTypeShift,
  145. // Register group (4 bits).
  146. // |........|........|....XXXX|........|
  147. kSignatureRegGroupShift = 8,
  148. kSignatureRegGroupMask = 0x0Fu << kSignatureRegGroupShift,
  149. // Memory base type (5 bits).
  150. // |........|........|........|XXXXX...|
  151. kSignatureMemBaseTypeShift = 3,
  152. kSignatureMemBaseTypeMask = 0x1Fu << kSignatureMemBaseTypeShift,
  153. // Memory index type (5 bits).
  154. // |........|........|...XXXXX|........|
  155. kSignatureMemIndexTypeShift = 8,
  156. kSignatureMemIndexTypeMask = 0x1Fu << kSignatureMemIndexTypeShift,
  157. // Memory base+index combined (10 bits).
  158. // |........|........|...XXXXX|XXXXX...|
  159. kSignatureMemBaseIndexShift = 3,
  160. kSignatureMemBaseIndexMask = 0x3FFu << kSignatureMemBaseIndexShift,
  161. // Memory address type (2 bits).
  162. // |........|........|.XX.....|........|
  163. kSignatureMemAddrTypeShift = 13,
  164. kSignatureMemAddrTypeMask = 0x03u << kSignatureMemAddrTypeShift,
  165. // This memory operand represents a home-slot or stack (BaseCompiler).
  166. // |........|........|X.......|........|
  167. kSignatureMemRegHomeShift = 15,
  168. kSignatureMemRegHomeFlag = 0x01u << kSignatureMemRegHomeShift,
  169. // Operand size (8 most significant bits).
  170. // |XXXXXXXX|........|........|........|
  171. kSignatureSizeShift = 24,
  172. kSignatureSizeMask = 0xFFu << kSignatureSizeShift
  173. };
  174. //! \endcond
  175. //! \cond INTERNAL
  176. //! Constants useful for VirtId <-> Index translation.
  177. enum VirtIdConstants : uint32_t {
  178. //! Minimum valid packed-id.
  179. kVirtIdMin = 256,
  180. //! Maximum valid packed-id, excludes Globals::kInvalidId.
  181. kVirtIdMax = Globals::kInvalidId - 1,
  182. //! Count of valid packed-ids.
  183. kVirtIdCount = uint32_t(kVirtIdMax - kVirtIdMin + 1)
  184. };
  185. //! Tests whether the given `id` is a valid virtual register id. Since AsmJit
  186. //! supports both physical and virtual registers it must be able to distinguish
  187. //! between these two. The idea is that physical registers are always limited
  188. //! in size, so virtual identifiers start from `kVirtIdMin` and end at
  189. //! `kVirtIdMax`.
  190. static ASMJIT_INLINE bool isVirtId(uint32_t id) noexcept { return id - kVirtIdMin < uint32_t(kVirtIdCount); }
  191. //! Converts a real-id into a packed-id that can be stored in Operand.
  192. static ASMJIT_INLINE uint32_t indexToVirtId(uint32_t id) noexcept { return id + kVirtIdMin; }
  193. //! Converts a packed-id back to real-id.
  194. static ASMJIT_INLINE uint32_t virtIdToIndex(uint32_t id) noexcept { return id - kVirtIdMin; }
  195. //! \endcond
  196. //! \name Construction & Destruction
  197. //! \{
  198. //! \cond INTERNAL
  199. //! Initializes a `BaseReg` operand from `signature` and register `id`.
  200. inline void _initReg(uint32_t signature, uint32_t id) noexcept {
  201. _signature = signature;
  202. _baseId = id;
  203. _data64 = 0;
  204. }
  205. //! Initializes the operand from `other` (used by operator overloads).
  206. inline void copyFrom(const Operand_& other) noexcept { memcpy(this, &other, sizeof(Operand_)); }
  207. //! \endcond
  208. //! Resets the `Operand` to none.
  209. //!
  210. //! None operand is defined the following way:
  211. //! - Its signature is zero (kOpNone, and the rest zero as well).
  212. //! - Its id is `0`.
  213. //! - The reserved8_4 field is set to `0`.
  214. //! - The reserved12_4 field is set to zero.
  215. //!
  216. //! In other words, reset operands have all members set to zero. Reset operand
  217. //! must match the Operand state right after its construction. Alternatively,
  218. //! if you have an array of operands, you can simply use `memset()`.
  219. //!
  220. //! ```
  221. //! using namespace asmjit;
  222. //!
  223. //! Operand a;
  224. //! Operand b;
  225. //! assert(a == b);
  226. //!
  227. //! b = x86::eax;
  228. //! assert(a != b);
  229. //!
  230. //! b.reset();
  231. //! assert(a == b);
  232. //!
  233. //! memset(&b, 0, sizeof(Operand));
  234. //! assert(a == b);
  235. //! ```
  236. inline void reset() noexcept {
  237. _signature = 0;
  238. _baseId = 0;
  239. _data64 = 0;
  240. }
  241. //! \}
  242. //! \name Operator Overloads
  243. //! \{
  244. constexpr bool operator==(const Operand_& other) const noexcept { return isEqual(other); }
  245. constexpr bool operator!=(const Operand_& other) const noexcept { return !isEqual(other); }
  246. //! \}
  247. //! \name Cast
  248. //! \{
  249. //! Casts this operand to `T` type.
  250. template<typename T>
  251. inline T& as() noexcept { return static_cast<T&>(*this); }
  252. //! Casts this operand to `T` type (const).
  253. template<typename T>
  254. inline const T& as() const noexcept { return static_cast<const T&>(*this); }
  255. //! \}
  256. //! \name Accessors
  257. //! \{
  258. //! Tests whether the operand matches the given signature `sign`.
  259. constexpr bool hasSignature(uint32_t signature) const noexcept { return _signature == signature; }
  260. //! Tests whether the operand matches the signature of the `other` operand.
  261. constexpr bool hasSignature(const Operand_& other) const noexcept { return _signature == other.signature(); }
  262. //! Returns operand signature as unsigned 32-bit integer.
  263. //!
  264. //! Signature is first 4 bytes of the operand data. It's used mostly for
  265. //! operand checking as it's much faster to check 4 bytes at once than having
  266. //! to check these bytes individually.
  267. constexpr uint32_t signature() const noexcept { return _signature; }
  268. //! Sets the operand signature, see `signature()`.
  269. //!
  270. //! \note Improper use of `setSignature()` can lead to hard-to-debug errors.
  271. inline void setSignature(uint32_t signature) noexcept { _signature = signature; }
  272. //! \cond INTERNAL
  273. template<uint32_t mask>
  274. constexpr bool _hasSignaturePart() const noexcept {
  275. return (_signature & mask) != 0;
  276. }
  277. template<uint32_t mask>
  278. constexpr uint32_t _getSignaturePart() const noexcept {
  279. return (_signature >> Support::constCtz(mask)) & (mask >> Support::constCtz(mask));
  280. }
  281. template<uint32_t mask>
  282. inline void _setSignaturePart(uint32_t value) noexcept {
  283. ASMJIT_ASSERT((value & ~(mask >> Support::constCtz(mask))) == 0);
  284. _signature = (_signature & ~mask) | (value << Support::constCtz(mask));
  285. }
  286. //! \endcond
  287. //! Returns the type of the operand, see `OpType`.
  288. constexpr uint32_t opType() const noexcept { return _getSignaturePart<kSignatureOpMask>(); }
  289. //! Tests whether the operand is none (`kOpNone`).
  290. constexpr bool isNone() const noexcept { return _signature == 0; }
  291. //! Tests whether the operand is a register (`kOpReg`).
  292. constexpr bool isReg() const noexcept { return opType() == kOpReg; }
  293. //! Tests whether the operand is a memory location (`kOpMem`).
  294. constexpr bool isMem() const noexcept { return opType() == kOpMem; }
  295. //! Tests whether the operand is an immediate (`kOpImm`).
  296. constexpr bool isImm() const noexcept { return opType() == kOpImm; }
  297. //! Tests whether the operand is a label (`kOpLabel`).
  298. constexpr bool isLabel() const noexcept { return opType() == kOpLabel; }
  299. //! Tests whether the operand is a physical register.
  300. constexpr bool isPhysReg() const noexcept { return isReg() && _baseId < 0xFFu; }
  301. //! Tests whether the operand is a virtual register.
  302. constexpr bool isVirtReg() const noexcept { return isReg() && _baseId > 0xFFu; }
  303. //! Tests whether the operand specifies a size (i.e. the size is not zero).
  304. constexpr bool hasSize() const noexcept { return _hasSignaturePart<kSignatureSizeMask>(); }
  305. //! Tests whether the size of the operand matches `size`.
  306. constexpr bool hasSize(uint32_t s) const noexcept { return size() == s; }
  307. //! Returns the size of the operand in bytes.
  308. //!
  309. //! The value returned depends on the operand type:
  310. //! * None - Should always return zero size.
  311. //! * Reg - Should always return the size of the register. If the register
  312. //! size depends on architecture (like `x86::CReg` and `x86::DReg`)
  313. //! the size returned should be the greatest possible (so it should
  314. //! return 64-bit size in such case).
  315. //! * Mem - Size is optional and will be in most cases zero.
  316. //! * Imm - Should always return zero size.
  317. //! * Label - Should always return zero size.
  318. constexpr uint32_t size() const noexcept { return _getSignaturePart<kSignatureSizeMask>(); }
  319. //! Returns the operand id.
  320. //!
  321. //! The value returned should be interpreted accordingly to the operand type:
  322. //! * None - Should be `0`.
  323. //! * Reg - Physical or virtual register id.
  324. //! * Mem - Multiple meanings - BASE address (register or label id), or
  325. //! high value of a 64-bit absolute address.
  326. //! * Imm - Should be `0`.
  327. //! * Label - Label id if it was created by using `newLabel()` or
  328. //! `Globals::kInvalidId` if the label is invalid or not
  329. //! initialized.
  330. constexpr uint32_t id() const noexcept { return _baseId; }
  331. //! Tests whether the operand is 100% equal to `other`.
  332. constexpr bool isEqual(const Operand_& other) const noexcept {
  333. return (_signature == other._signature) &
  334. (_baseId == other._baseId ) &
  335. (_data64 == other._data64 ) ;
  336. }
  337. //! Tests whether the operand is a register matching `rType`.
  338. constexpr bool isReg(uint32_t rType) const noexcept {
  339. return (_signature & (kSignatureOpMask | kSignatureRegTypeMask)) ==
  340. ((kOpReg << kSignatureOpShift) | (rType << kSignatureRegTypeShift));
  341. }
  342. //! Tests whether the operand is register and of `rType` and `rId`.
  343. constexpr bool isReg(uint32_t rType, uint32_t rId) const noexcept {
  344. return isReg(rType) && id() == rId;
  345. }
  346. //! Tests whether the operand is a register or memory.
  347. constexpr bool isRegOrMem() const noexcept {
  348. return Support::isBetween<uint32_t>(opType(), kOpReg, kOpMem);
  349. }
  350. //! \}
  351. };
  352. // ============================================================================
  353. // [asmjit::Operand]
  354. // ============================================================================
  355. //! Operand can contain register, memory location, immediate, or label.
  356. class Operand : public Operand_ {
  357. public:
  358. //! \name Construction & Destruction
  359. //! \{
  360. //! Creates `kOpNone` operand having all members initialized to zero.
  361. constexpr Operand() noexcept
  362. : Operand_{ kOpNone, 0u, {{ 0u, 0u }}} {}
  363. //! Creates a cloned `other` operand.
  364. constexpr Operand(const Operand& other) noexcept = default;
  365. //! Creates a cloned `other` operand.
  366. constexpr explicit Operand(const Operand_& other)
  367. : Operand_(other) {}
  368. //! Creates an operand initialized to raw `[u0, u1, u2, u3]` values.
  369. constexpr Operand(Globals::Init_, uint32_t u0, uint32_t u1, uint32_t u2, uint32_t u3) noexcept
  370. : Operand_{ u0, u1, {{ u2, u3 }}} {}
  371. //! Creates an uninitialized operand (dangerous).
  372. inline explicit Operand(Globals::NoInit_) noexcept {}
  373. //! \}
  374. //! \name Operator Overloads
  375. //! \{
  376. inline Operand& operator=(const Operand& other) noexcept = default;
  377. inline Operand& operator=(const Operand_& other) noexcept { return operator=(static_cast<const Operand&>(other)); }
  378. //! \}
  379. //! \name Utilities
  380. //! \{
  381. //! Clones this operand and returns its copy.
  382. constexpr Operand clone() const noexcept { return Operand(*this); }
  383. //! \}
  384. };
  385. static_assert(sizeof(Operand) == 16, "asmjit::Operand must be exactly 16 bytes long");
  386. namespace Globals {
  387. //! A default-constructed operand of `Operand_::kOpNone` type.
  388. static constexpr const Operand none;
  389. }
  390. // ============================================================================
  391. // [asmjit::Label]
  392. // ============================================================================
  393. //! Label (jump target or data location).
  394. //!
  395. //! Label represents a location in code typically used as a jump target, but
  396. //! may be also a reference to some data or a static variable. Label has to be
  397. //! explicitly created by BaseEmitter.
  398. //!
  399. //! Example of using labels:
  400. //!
  401. //! ```
  402. //! // Create some emitter (for example x86::Assembler).
  403. //! x86::Assembler a;
  404. //!
  405. //! // Create Label instance.
  406. //! Label L1 = a.newLabel();
  407. //!
  408. //! // ... your code ...
  409. //!
  410. //! // Using label.
  411. //! a.jump(L1);
  412. //!
  413. //! // ... your code ...
  414. //!
  415. //! // Bind label to the current position, see `BaseEmitter::bind()`.
  416. //! a.bind(L1);
  417. //! ```
  418. class Label : public Operand {
  419. public:
  420. //! Type of the Label.
  421. enum LabelType : uint32_t {
  422. //! Anonymous (unnamed) label.
  423. kTypeAnonymous = 0,
  424. //! Local label (always has parentId).
  425. kTypeLocal = 1,
  426. //! Global label (never has parentId).
  427. kTypeGlobal = 2,
  428. //! Number of label types.
  429. kTypeCount = 3
  430. };
  431. // TODO: Find a better place, find a better name.
  432. enum {
  433. //! Label tag is used as a sub-type, forming a unique signature across all
  434. //! operand types as 0x1 is never associated with any register (reg-type).
  435. //! This means that a memory operand's BASE register can be constructed
  436. //! from virtually any operand (register vs. label) by just assigning its
  437. //! type (reg type or label-tag) and operand id.
  438. kLabelTag = 0x1
  439. };
  440. //! \name Construction & Destruction
  441. //! \{
  442. //! Creates a label operand without ID (you must set the ID to make it valid).
  443. constexpr Label() noexcept
  444. : Operand(Globals::Init, kOpLabel, Globals::kInvalidId, 0, 0) {}
  445. //! Creates a cloned label operand of `other` .
  446. constexpr Label(const Label& other) noexcept
  447. : Operand(other) {}
  448. //! Creates a label operand of the given `id`.
  449. constexpr explicit Label(uint32_t id) noexcept
  450. : Operand(Globals::Init, kOpLabel, id, 0, 0) {}
  451. inline explicit Label(Globals::NoInit_) noexcept
  452. : Operand(Globals::NoInit) {}
  453. //! Resets the label, will reset all properties and set its ID to `Globals::kInvalidId`.
  454. inline void reset() noexcept {
  455. _signature = kOpLabel;
  456. _baseId = Globals::kInvalidId;
  457. _data64 = 0;
  458. }
  459. //! \}
  460. //! \name Overloaded Operators
  461. //! \{
  462. inline Label& operator=(const Label& other) noexcept = default;
  463. //! \}
  464. //! \name Accessors
  465. //! \{
  466. //! Tests whether the label was created by CodeHolder and/or an attached emitter.
  467. constexpr bool isValid() const noexcept { return _baseId != Globals::kInvalidId; }
  468. //! Sets the label `id`.
  469. inline void setId(uint32_t id) noexcept { _baseId = id; }
  470. //! \}
  471. };
  472. // ============================================================================
  473. // [asmjit::BaseRegTraits]
  474. // ============================================================================
  475. //! \cond INTERNAL
  476. //! Default register traits.
  477. struct BaseRegTraits {
  478. //! RegType is not valid by default.
  479. static constexpr uint32_t kValid = 0;
  480. //! Count of registers (0 if none).
  481. static constexpr uint32_t kCount = 0;
  482. //! Everything is void by default.
  483. static constexpr uint32_t kTypeId = 0;
  484. //! Zero type by default.
  485. static constexpr uint32_t kType = 0;
  486. //! Zero group by default.
  487. static constexpr uint32_t kGroup = 0;
  488. //! No size by default.
  489. static constexpr uint32_t kSize = 0;
  490. //! Empty signature by default.
  491. static constexpr uint32_t kSignature = Operand::kOpReg;
  492. };
  493. //! \endcond
  494. // ============================================================================
  495. // [asmjit::BaseReg]
  496. // ============================================================================
  497. //! Structure that allows to extract a register information based on the signature.
  498. //!
  499. //! This information is compatible with operand's signature (32-bit integer)
  500. //! and `RegInfo` just provides easy way to access it.
  501. struct RegInfo {
  502. inline void reset() noexcept { _signature = 0; }
  503. inline void setSignature(uint32_t signature) noexcept { _signature = signature; }
  504. template<uint32_t mask>
  505. constexpr uint32_t _getSignaturePart() const noexcept {
  506. return (_signature >> Support::constCtz(mask)) & (mask >> Support::constCtz(mask));
  507. }
  508. constexpr bool isValid() const noexcept { return _signature != 0; }
  509. constexpr uint32_t signature() const noexcept { return _signature; }
  510. constexpr uint32_t opType() const noexcept { return _getSignaturePart<Operand::kSignatureOpMask>(); }
  511. constexpr uint32_t group() const noexcept { return _getSignaturePart<Operand::kSignatureRegGroupMask>(); }
  512. constexpr uint32_t type() const noexcept { return _getSignaturePart<Operand::kSignatureRegTypeMask>(); }
  513. constexpr uint32_t size() const noexcept { return _getSignaturePart<Operand::kSignatureSizeMask>(); }
  514. uint32_t _signature;
  515. };
  516. //! Physical/Virtual register operand.
  517. class BaseReg : public Operand {
  518. public:
  519. //! Architecture neutral register types.
  520. //!
  521. //! These must be reused by any platform that contains that types. All GP
  522. //! and VEC registers are also allowed by design to be part of a BASE|INDEX
  523. //! of a memory operand.
  524. enum RegType : uint32_t {
  525. //! No register - unused, invalid, multiple meanings.
  526. kTypeNone = 0,
  527. // (1 is used as a LabelTag)
  528. //! 8-bit low general purpose register (X86).
  529. kTypeGp8Lo = 2,
  530. //! 8-bit high general purpose register (X86).
  531. kTypeGp8Hi = 3,
  532. //! 16-bit general purpose register (X86).
  533. kTypeGp16 = 4,
  534. //! 32-bit general purpose register (X86|ARM).
  535. kTypeGp32 = 5,
  536. //! 64-bit general purpose register (X86|ARM).
  537. kTypeGp64 = 6,
  538. //! 32-bit view of a vector register (ARM).
  539. kTypeVec32 = 7,
  540. //! 64-bit view of a vector register (ARM).
  541. kTypeVec64 = 8,
  542. //! 128-bit view of a vector register (X86|ARM).
  543. kTypeVec128 = 9,
  544. //! 256-bit view of a vector register (X86).
  545. kTypeVec256 = 10,
  546. //! 512-bit view of a vector register (X86).
  547. kTypeVec512 = 11,
  548. //! 1024-bit view of a vector register (future).
  549. kTypeVec1024 = 12,
  550. //! Other0 register, should match `kOther0` group.
  551. kTypeOther0 = 13,
  552. //! Other1 register, should match `kOther1` group.
  553. kTypeOther1 = 14,
  554. //! Universal id of IP/PC register (if separate).
  555. kTypeIP = 15,
  556. //! Start of platform dependent register types (must be honored).
  557. kTypeCustom = 16,
  558. //! Maximum possible register id of all architectures.
  559. kTypeMax = 31
  560. };
  561. //! Register group (architecture neutral), and some limits.
  562. enum RegGroup : uint32_t {
  563. //! General purpose register group compatible with all backends.
  564. kGroupGp = 0,
  565. //! Vector register group compatible with all backends.
  566. kGroupVec = 1,
  567. //! Group that is architecture dependent.
  568. kGroupOther0 = 2,
  569. //! Group that is architecture dependent.
  570. kGroupOther1 = 3,
  571. //! Count of register groups used by virtual registers.
  572. kGroupVirt = 4,
  573. //! Count of register groups used by physical registers.
  574. kGroupCount = 16
  575. };
  576. enum Id : uint32_t {
  577. //! None or any register (mostly internal).
  578. kIdBad = 0xFFu
  579. };
  580. static constexpr uint32_t kSignature = kOpReg;
  581. //! \name Construction & Destruction
  582. //! \{
  583. //! Creates a dummy register operand.
  584. constexpr BaseReg() noexcept
  585. : Operand(Globals::Init, kSignature, kIdBad, 0, 0) {}
  586. //! Creates a new register operand which is the same as `other` .
  587. constexpr BaseReg(const BaseReg& other) noexcept
  588. : Operand(other) {}
  589. //! Creates a new register operand compatible with `other`, but with a different `rId`.
  590. constexpr BaseReg(const BaseReg& other, uint32_t rId) noexcept
  591. : Operand(Globals::Init, other._signature, rId, 0, 0) {}
  592. //! Creates a register initialized to `signature` and `rId`.
  593. constexpr BaseReg(uint32_t signature, uint32_t rId) noexcept
  594. : Operand(Globals::Init, signature, rId, 0, 0) {}
  595. inline explicit BaseReg(Globals::NoInit_) noexcept
  596. : Operand(Globals::NoInit) {}
  597. //! \}
  598. //! \name Overloaded Operators
  599. //! \{
  600. inline BaseReg& operator=(const BaseReg& other) noexcept = default;
  601. //! \}
  602. //! \name Accessors
  603. //! \{
  604. //! Tests whether this register is the same as `other`.
  605. //!
  606. //! This is just an optimization. Registers by default only use the first
  607. //! 8 bytes of the Operand, so this method takes advantage of this knowledge
  608. //! and only compares these 8 bytes. If both operands were created correctly
  609. //! then `isEqual()` and `isSame()` should give the same answer, however, if
  610. //! some one of the two operand contains a garbage or other metadata in the
  611. //! upper 8 bytes then `isSame()` may return `true` in cases where `isEqual()`
  612. //! returns false.
  613. constexpr bool isSame(const BaseReg& other) const noexcept {
  614. return (_signature == other._signature) &
  615. (_baseId == other._baseId ) ;
  616. }
  617. //! Tests whether the register is valid (either virtual or physical).
  618. constexpr bool isValid() const noexcept { return (_signature != 0) & (_baseId != kIdBad); }
  619. //! Tests whether this is a physical register.
  620. constexpr bool isPhysReg() const noexcept { return _baseId < kIdBad; }
  621. //! Tests whether this is a virtual register.
  622. constexpr bool isVirtReg() const noexcept { return _baseId > kIdBad; }
  623. //! Tests whether the register type matches `type` - same as `isReg(type)`, provided for convenience.
  624. constexpr bool isType(uint32_t type) const noexcept { return (_signature & kSignatureRegTypeMask) == (type << kSignatureRegTypeShift); }
  625. //! Tests whether the register group matches `group`.
  626. constexpr bool isGroup(uint32_t group) const noexcept { return (_signature & kSignatureRegGroupMask) == (group << kSignatureRegGroupShift); }
  627. //! Tests whether the register is a general purpose register (any size).
  628. constexpr bool isGp() const noexcept { return isGroup(kGroupGp); }
  629. //! Tests whether the register is a vector register.
  630. constexpr bool isVec() const noexcept { return isGroup(kGroupVec); }
  631. using Operand_::isReg;
  632. //! Same as `isType()`, provided for convenience.
  633. constexpr bool isReg(uint32_t rType) const noexcept { return isType(rType); }
  634. //! Tests whether the register type matches `type` and register id matches `rId`.
  635. constexpr bool isReg(uint32_t rType, uint32_t rId) const noexcept { return isType(rType) && id() == rId; }
  636. //! Returns the type of the register.
  637. constexpr uint32_t type() const noexcept { return _getSignaturePart<kSignatureRegTypeMask>(); }
  638. //! Returns the register group.
  639. constexpr uint32_t group() const noexcept { return _getSignaturePart<kSignatureRegGroupMask>(); }
  640. //! Clones the register operand.
  641. constexpr BaseReg clone() const noexcept { return BaseReg(*this); }
  642. //! Casts this register to `RegT` by also changing its signature.
  643. //!
  644. //! \note Improper use of `cloneAs()` can lead to hard-to-debug errors.
  645. template<typename RegT>
  646. constexpr RegT cloneAs() const noexcept { return RegT(RegT::kSignature, id()); }
  647. //! Casts this register to `other` by also changing its signature.
  648. //!
  649. //! \note Improper use of `cloneAs()` can lead to hard-to-debug errors.
  650. template<typename RegT>
  651. constexpr RegT cloneAs(const RegT& other) const noexcept { return RegT(other.signature(), id()); }
  652. //! Sets the register id to `rId`.
  653. inline void setId(uint32_t rId) noexcept { _baseId = rId; }
  654. //! Sets a 32-bit operand signature based on traits of `RegT`.
  655. template<typename RegT>
  656. inline void setSignatureT() noexcept { _signature = RegT::kSignature; }
  657. //! Sets the register `signature` and `rId`.
  658. inline void setSignatureAndId(uint32_t signature, uint32_t rId) noexcept {
  659. _signature = signature;
  660. _baseId = rId;
  661. }
  662. //! \}
  663. //! \name Static Functions
  664. //! \{
  665. static inline bool isGp(const Operand_& op) noexcept {
  666. // Check operand type and register group. Not interested in register type and size.
  667. const uint32_t kSgn = (kOpReg << kSignatureOpShift ) |
  668. (kGroupGp << kSignatureRegGroupShift) ;
  669. return (op.signature() & (kSignatureOpMask | kSignatureRegGroupMask)) == kSgn;
  670. }
  671. //! Tests whether the `op` operand is either a low or high 8-bit GPB register.
  672. static inline bool isVec(const Operand_& op) noexcept {
  673. // Check operand type and register group. Not interested in register type and size.
  674. const uint32_t kSgn = (kOpReg << kSignatureOpShift ) |
  675. (kGroupVec << kSignatureRegGroupShift) ;
  676. return (op.signature() & (kSignatureOpMask | kSignatureRegGroupMask)) == kSgn;
  677. }
  678. static inline bool isGp(const Operand_& op, uint32_t rId) noexcept { return isGp(op) & (op.id() == rId); }
  679. static inline bool isVec(const Operand_& op, uint32_t rId) noexcept { return isVec(op) & (op.id() == rId); }
  680. //! \}
  681. };
  682. // ============================================================================
  683. // [asmjit::RegOnly]
  684. // ============================================================================
  685. //! RegOnly is 8-byte version of `BaseReg` that allows to store either register
  686. //! or nothing.
  687. //!
  688. //! This class was designed to decrease the space consumed by each extra "operand"
  689. //! in `BaseEmitter` and `InstNode` classes.
  690. struct RegOnly {
  691. //! Type of the operand, either `kOpNone` or `kOpReg`.
  692. uint32_t _signature;
  693. //! Physical or virtual register id.
  694. uint32_t _id;
  695. //! \name Construction & Destruction
  696. //! \{
  697. //! Initializes the `RegOnly` instance to hold register `signature` and `id`.
  698. inline void init(uint32_t signature, uint32_t id) noexcept {
  699. _signature = signature;
  700. _id = id;
  701. }
  702. inline void init(const BaseReg& reg) noexcept { init(reg.signature(), reg.id()); }
  703. inline void init(const RegOnly& reg) noexcept { init(reg.signature(), reg.id()); }
  704. //! Resets the `RegOnly` members to zeros (none).
  705. inline void reset() noexcept { init(0, 0); }
  706. //! \}
  707. //! \name Accessors
  708. //! \{
  709. //! Tests whether this ExtraReg is none (same as calling `Operand_::isNone()`).
  710. constexpr bool isNone() const noexcept { return _signature == 0; }
  711. //! Tests whether the register is valid (either virtual or physical).
  712. constexpr bool isReg() const noexcept { return _signature != 0; }
  713. //! Tests whether this is a physical register.
  714. constexpr bool isPhysReg() const noexcept { return _id < BaseReg::kIdBad; }
  715. //! Tests whether this is a virtual register (used by `BaseCompiler`).
  716. constexpr bool isVirtReg() const noexcept { return _id > BaseReg::kIdBad; }
  717. //! Returns the register signature or 0 if no register is assigned.
  718. constexpr uint32_t signature() const noexcept { return _signature; }
  719. //! Returns the register id.
  720. //!
  721. //! \note Always check whether the register is assigned before using the
  722. //! returned identifier as non-assigned `RegOnly` instance would return
  723. //! zero id, which is still a valid register id.
  724. constexpr uint32_t id() const noexcept { return _id; }
  725. //! Sets the register id.
  726. inline void setId(uint32_t id) noexcept { _id = id; }
  727. //! \cond INTERNAL
  728. //!
  729. //! Extracts information from operand's signature.
  730. template<uint32_t mask>
  731. constexpr uint32_t _getSignaturePart() const noexcept {
  732. return (_signature >> Support::constCtz(mask)) & (mask >> Support::constCtz(mask));
  733. }
  734. //! \endcond
  735. //! Returns the type of the register.
  736. constexpr uint32_t type() const noexcept { return _getSignaturePart<Operand::kSignatureRegTypeMask>(); }
  737. //! Returns the register group.
  738. constexpr uint32_t group() const noexcept { return _getSignaturePart<Operand::kSignatureRegGroupMask>(); }
  739. //! \}
  740. //! \name Utilities
  741. //! \{
  742. //! Converts this ExtraReg to a real `RegT` operand.
  743. template<typename RegT>
  744. constexpr RegT toReg() const noexcept { return RegT(_signature, _id); }
  745. //! \}
  746. };
  747. // ============================================================================
  748. // [asmjit::BaseMem]
  749. // ============================================================================
  750. //! Base class for all memory operands.
  751. //!
  752. //! \note It's tricky to pack all possible cases that define a memory operand
  753. //! into just 16 bytes. The `BaseMem` splits data into the following parts:
  754. //!
  755. //! BASE - Base register or label - requires 36 bits total. 4 bits are used to
  756. //! encode the type of the BASE operand (label vs. register type) and
  757. //! the remaining 32 bits define the BASE id, which can be a physical or
  758. //! virtual register index. If BASE type is zero, which is never used as
  759. //! a register-type and label doesn't use it as well then BASE field
  760. //! contains a high DWORD of a possible 64-bit absolute address, which is
  761. //! possible on X64.
  762. //!
  763. //! INDEX - Index register (or theoretically Label, which doesn't make sense).
  764. //! Encoding is similar to BASE - it also requires 36 bits and splits
  765. //! the encoding to INDEX type (4 bits defining the register type) and
  766. //! id (32-bits).
  767. //!
  768. //! OFFSET - A relative offset of the address. Basically if BASE is specified
  769. //! the relative displacement adjusts BASE and an optional INDEX. if
  770. //! BASE is not specified then the OFFSET should be considered as ABSOLUTE
  771. //! address (at least on X86). In that case its low 32 bits are stored in
  772. //! DISPLACEMENT field and the remaining high 32 bits are stored in BASE.
  773. //!
  774. //! OTHER - There is rest 8 bits that can be used for whatever purpose. The
  775. //! x86::Mem operand uses these bits to store segment override prefix and
  776. //! index shift (scale).
  777. class BaseMem : public Operand {
  778. public:
  779. enum AddrType : uint32_t {
  780. kAddrTypeDefault = 0,
  781. kAddrTypeAbs = 1,
  782. kAddrTypeRel = 2
  783. };
  784. // Shortcuts.
  785. enum SignatureMem : uint32_t {
  786. kSignatureMemAbs = kAddrTypeAbs << kSignatureMemAddrTypeShift,
  787. kSignatureMemRel = kAddrTypeRel << kSignatureMemAddrTypeShift
  788. };
  789. //! \cond INTERNAL
  790. //! Used internally to construct `BaseMem` operand from decomposed data.
  791. struct Decomposed {
  792. uint32_t baseType;
  793. uint32_t baseId;
  794. uint32_t indexType;
  795. uint32_t indexId;
  796. int32_t offset;
  797. uint32_t size;
  798. uint32_t flags;
  799. };
  800. //! \endcond
  801. //! \name Construction & Destruction
  802. //! \{
  803. //! Creates a default `BaseMem` operand, that points to [0].
  804. constexpr BaseMem() noexcept
  805. : Operand(Globals::Init, kOpMem, 0, 0, 0) {}
  806. //! Creates a `BaseMem` operand that is a clone of `other`.
  807. constexpr BaseMem(const BaseMem& other) noexcept
  808. : Operand(other) {}
  809. //! \cond INTERNAL
  810. //! Creates a `BaseMem` operand from 4 integers as used by `Operand_` struct.
  811. constexpr BaseMem(Globals::Init_, uint32_t u0, uint32_t u1, uint32_t u2, uint32_t u3) noexcept
  812. : Operand(Globals::Init, u0, u1, u2, u3) {}
  813. constexpr BaseMem(const Decomposed& d) noexcept
  814. : Operand(Globals::Init,
  815. kOpMem | (d.baseType << kSignatureMemBaseTypeShift )
  816. | (d.indexType << kSignatureMemIndexTypeShift)
  817. | (d.size << kSignatureSizeShift )
  818. | d.flags,
  819. d.baseId,
  820. d.indexId,
  821. uint32_t(d.offset)) {}
  822. //! \endcond
  823. //! Creates a completely uninitialized `BaseMem` operand.
  824. inline explicit BaseMem(Globals::NoInit_) noexcept
  825. : Operand(Globals::NoInit) {}
  826. //! Resets the memory operand - after the reset the memory points to [0].
  827. inline void reset() noexcept {
  828. _signature = kOpMem;
  829. _baseId = 0;
  830. _data64 = 0;
  831. }
  832. //! \}
  833. //! \name Overloaded Operators
  834. //! \{
  835. inline BaseMem& operator=(const BaseMem& other) noexcept { copyFrom(other); return *this; }
  836. //! \}
  837. //! \name Accessors
  838. //! \{
  839. //! Clones the memory operand.
  840. constexpr BaseMem clone() const noexcept { return BaseMem(*this); }
  841. constexpr uint32_t addrType() const noexcept { return _getSignaturePart<kSignatureMemAddrTypeMask>(); }
  842. inline void setAddrType(uint32_t addrType) noexcept { _setSignaturePart<kSignatureMemAddrTypeMask>(addrType); }
  843. inline void resetAddrType() noexcept { _setSignaturePart<kSignatureMemAddrTypeMask>(0); }
  844. constexpr bool isAbs() const noexcept { return addrType() == kAddrTypeAbs; }
  845. inline void setAbs() noexcept { setAddrType(kAddrTypeAbs); }
  846. constexpr bool isRel() const noexcept { return addrType() == kAddrTypeRel; }
  847. inline void setRel() noexcept { setAddrType(kAddrTypeRel); }
  848. constexpr bool isRegHome() const noexcept { return _hasSignaturePart<kSignatureMemRegHomeFlag>(); }
  849. inline void setRegHome() noexcept { _signature |= kSignatureMemRegHomeFlag; }
  850. inline void clearRegHome() noexcept { _signature &= ~kSignatureMemRegHomeFlag; }
  851. //! Tests whether the memory operand has a BASE register or label specified.
  852. constexpr bool hasBase() const noexcept { return (_signature & kSignatureMemBaseTypeMask) != 0; }
  853. //! Tests whether the memory operand has an INDEX register specified.
  854. constexpr bool hasIndex() const noexcept { return (_signature & kSignatureMemIndexTypeMask) != 0; }
  855. //! Tests whether the memory operand has BASE and INDEX register.
  856. constexpr bool hasBaseOrIndex() const noexcept { return (_signature & kSignatureMemBaseIndexMask) != 0; }
  857. //! Tests whether the memory operand has BASE and INDEX register.
  858. constexpr bool hasBaseAndIndex() const noexcept { return (_signature & kSignatureMemBaseTypeMask) != 0 && (_signature & kSignatureMemIndexTypeMask) != 0; }
  859. //! Tests whether the BASE operand is a register (registers start after `kLabelTag`).
  860. constexpr bool hasBaseReg() const noexcept { return (_signature & kSignatureMemBaseTypeMask) > (Label::kLabelTag << kSignatureMemBaseTypeShift); }
  861. //! Tests whether the BASE operand is a label.
  862. constexpr bool hasBaseLabel() const noexcept { return (_signature & kSignatureMemBaseTypeMask) == (Label::kLabelTag << kSignatureMemBaseTypeShift); }
  863. //! Tests whether the INDEX operand is a register (registers start after `kLabelTag`).
  864. constexpr bool hasIndexReg() const noexcept { return (_signature & kSignatureMemIndexTypeMask) > (Label::kLabelTag << kSignatureMemIndexTypeShift); }
  865. //! Returns the type of the BASE register (0 if this memory operand doesn't
  866. //! use the BASE register).
  867. //!
  868. //! \note If the returned type is one (a value never associated to a register
  869. //! type) the BASE is not register, but it's a label. One equals to `kLabelTag`.
  870. //! You should always check `hasBaseLabel()` before using `baseId()` result.
  871. constexpr uint32_t baseType() const noexcept { return _getSignaturePart<kSignatureMemBaseTypeMask>(); }
  872. //! Returns the type of an INDEX register (0 if this memory operand doesn't
  873. //! use the INDEX register).
  874. constexpr uint32_t indexType() const noexcept { return _getSignaturePart<kSignatureMemIndexTypeMask>(); }
  875. //! This is used internally for BASE+INDEX validation.
  876. constexpr uint32_t baseAndIndexTypes() const noexcept { return _getSignaturePart<kSignatureMemBaseIndexMask>(); }
  877. //! Returns both BASE (4:0 bits) and INDEX (9:5 bits) types combined into a
  878. //! single value.
  879. //!
  880. //! \remarks Returns id of the BASE register or label (if the BASE was
  881. //! specified as label).
  882. constexpr uint32_t baseId() const noexcept { return _baseId; }
  883. //! Returns the id of the INDEX register.
  884. constexpr uint32_t indexId() const noexcept { return _mem.indexId; }
  885. //! Sets the id of the BASE register (without modifying its type).
  886. inline void setBaseId(uint32_t rId) noexcept { _baseId = rId; }
  887. //! Sets the id of the INDEX register (without modifying its type).
  888. inline void setIndexId(uint32_t rId) noexcept { _mem.indexId = rId; }
  889. //! Sets the base register to type and id of the given `base` operand.
  890. inline void setBase(const BaseReg& base) noexcept { return _setBase(base.type(), base.id()); }
  891. //! Sets the index register to type and id of the given `index` operand.
  892. inline void setIndex(const BaseReg& index) noexcept { return _setIndex(index.type(), index.id()); }
  893. inline void _setBase(uint32_t rType, uint32_t rId) noexcept {
  894. _setSignaturePart<kSignatureMemBaseTypeMask>(rType);
  895. _baseId = rId;
  896. }
  897. inline void _setIndex(uint32_t rType, uint32_t rId) noexcept {
  898. _setSignaturePart<kSignatureMemIndexTypeMask>(rType);
  899. _mem.indexId = rId;
  900. }
  901. //! Resets the memory operand's BASE register or label.
  902. inline void resetBase() noexcept { _setBase(0, 0); }
  903. //! Resets the memory operand's INDEX register.
  904. inline void resetIndex() noexcept { _setIndex(0, 0); }
  905. //! Sets the memory operand size (in bytes).
  906. inline void setSize(uint32_t size) noexcept { _setSignaturePart<kSignatureSizeMask>(size); }
  907. //! Tests whether the memory operand has a 64-bit offset or absolute address.
  908. //!
  909. //! If this is true then `hasBase()` must always report false.
  910. constexpr bool isOffset64Bit() const noexcept { return baseType() == 0; }
  911. //! Tests whether the memory operand has a non-zero offset or absolute address.
  912. constexpr bool hasOffset() const noexcept {
  913. return (_mem.offsetLo32 | uint32_t(_baseId & Support::bitMaskFromBool<uint32_t>(isOffset64Bit()))) != 0;
  914. }
  915. //! Returns either relative offset or absolute address as 64-bit integer.
  916. constexpr int64_t offset() const noexcept {
  917. return isOffset64Bit() ? int64_t(uint64_t(_mem.offsetLo32) | (uint64_t(_baseId) << 32))
  918. : int64_t(int32_t(_mem.offsetLo32)); // Sign extend 32-bit offset.
  919. }
  920. //! Returns a 32-bit low part of a 64-bit offset or absolute address.
  921. constexpr int32_t offsetLo32() const noexcept { return int32_t(_mem.offsetLo32); }
  922. //! Returns a 32-but high part of a 64-bit offset or absolute address.
  923. //!
  924. //! \note This function is UNSAFE and returns garbage if `isOffset64Bit()`
  925. //! returns false. Never use it blindly without checking it first.
  926. constexpr int32_t offsetHi32() const noexcept { return int32_t(_baseId); }
  927. //! Sets a 64-bit offset or an absolute address to `offset`.
  928. //!
  929. //! \note This functions attempts to set both high and low parts of a 64-bit
  930. //! offset, however, if the operand has a BASE register it will store only the
  931. //! low 32 bits of the offset / address as there is no way to store both BASE
  932. //! and 64-bit offset, and there is currently no architecture that has such
  933. //! capability targeted by AsmJit.
  934. inline void setOffset(int64_t offset) noexcept {
  935. uint32_t lo = uint32_t(uint64_t(offset) & 0xFFFFFFFFu);
  936. uint32_t hi = uint32_t(uint64_t(offset) >> 32);
  937. uint32_t hiMsk = Support::bitMaskFromBool<uint32_t>(isOffset64Bit());
  938. _mem.offsetLo32 = lo;
  939. _baseId = (hi & hiMsk) | (_baseId & ~hiMsk);
  940. }
  941. //! Sets a low 32-bit offset to `offset` (don't use without knowing how BaseMem works).
  942. inline void setOffsetLo32(int32_t offset) noexcept { _mem.offsetLo32 = uint32_t(offset); }
  943. //! Adjusts the offset by `offset`.
  944. //!
  945. //! \note This is a fast function that doesn't use the HI 32-bits of a
  946. //! 64-bit offset. Use it only if you know that there is a BASE register
  947. //! and the offset is only 32 bits anyway.
  948. //! Adjusts the offset by a 64-bit `offset`.
  949. inline void addOffset(int64_t offset) noexcept {
  950. if (isOffset64Bit()) {
  951. int64_t result = offset + int64_t(uint64_t(_mem.offsetLo32) | (uint64_t(_baseId) << 32));
  952. _mem.offsetLo32 = uint32_t(uint64_t(result) & 0xFFFFFFFFu);
  953. _baseId = uint32_t(uint64_t(result) >> 32);
  954. }
  955. else {
  956. _mem.offsetLo32 += uint32_t(uint64_t(offset) & 0xFFFFFFFFu);
  957. }
  958. }
  959. //! Adds `offset` to a low 32-bit offset part (don't use without knowing how
  960. //! BaseMem works).
  961. inline void addOffsetLo32(int32_t offset) noexcept { _mem.offsetLo32 += uint32_t(offset); }
  962. //! Resets the memory offset to zero.
  963. inline void resetOffset() noexcept { setOffset(0); }
  964. //! Resets the lo part of the memory offset to zero (don't use without knowing
  965. //! how BaseMem works).
  966. inline void resetOffsetLo32() noexcept { setOffsetLo32(0); }
  967. //! \}
  968. };
  969. // ============================================================================
  970. // [asmjit::Imm]
  971. // ============================================================================
  972. //! Immediate operand.
  973. //!
  974. //! Immediate operand is usually part of instruction itself. It's inlined after
  975. //! or before the instruction opcode. Immediates can be only signed or unsigned
  976. //! integers.
  977. //!
  978. //! To create an immediate operand use `asmjit::imm()` helper, which can be used
  979. //! with any type, not just the default 64-bit int.
  980. class Imm : public Operand {
  981. public:
  982. //! \name Construction & Destruction
  983. //! \{
  984. //! Creates a new immediate value (initial value is 0).
  985. constexpr Imm() noexcept
  986. : Operand(Globals::Init, kOpImm, 0, 0, 0) {}
  987. //! Creates a new immediate value from `other`.
  988. constexpr Imm(const Imm& other) noexcept
  989. : Operand(other) {}
  990. //! Creates a new signed immediate value, assigning the value to `val`.
  991. constexpr explicit Imm(int64_t val) noexcept
  992. : Operand(Globals::Init, kOpImm, 0, Support::unpackU32At0(val), Support::unpackU32At1(val)) {}
  993. inline explicit Imm(Globals::NoInit_) noexcept
  994. : Operand(Globals::NoInit) {}
  995. //! \}
  996. //! \name Overloaded Operators
  997. //! \{
  998. //! Assigns the value of the `other` operand to this immediate.
  999. inline Imm& operator=(const Imm& other) noexcept { copyFrom(other); return *this; }
  1000. //! \}
  1001. //! \name Accessors
  1002. //! \{
  1003. //! Tests whether the immediate can be casted to 8-bit signed integer.
  1004. constexpr bool isInt8() const noexcept { return Support::isInt8(int64_t(_data64)); }
  1005. //! Tests whether the immediate can be casted to 8-bit unsigned integer.
  1006. constexpr bool isUInt8() const noexcept { return Support::isUInt8(int64_t(_data64)); }
  1007. //! Tests whether the immediate can be casted to 16-bit signed integer.
  1008. constexpr bool isInt16() const noexcept { return Support::isInt16(int64_t(_data64)); }
  1009. //! Tests whether the immediate can be casted to 16-bit unsigned integer.
  1010. constexpr bool isUInt16() const noexcept { return Support::isUInt16(int64_t(_data64)); }
  1011. //! Tests whether the immediate can be casted to 32-bit signed integer.
  1012. constexpr bool isInt32() const noexcept { return Support::isInt32(int64_t(_data64)); }
  1013. //! Tests whether the immediate can be casted to 32-bit unsigned integer.
  1014. constexpr bool isUInt32() const noexcept { return Support::isUInt32(int64_t(_data64)); }
  1015. //! Returns immediate value as 8-bit signed integer, possibly cropped.
  1016. constexpr int8_t i8() const noexcept { return int8_t(_data64 & 0xFFu); }
  1017. //! Returns immediate value as 8-bit unsigned integer, possibly cropped.
  1018. constexpr uint8_t u8() const noexcept { return uint8_t(_data64 & 0xFFu); }
  1019. //! Returns immediate value as 16-bit signed integer, possibly cropped.
  1020. constexpr int16_t i16() const noexcept { return int16_t(_data64 & 0xFFFFu);}
  1021. //! Returns immediate value as 16-bit unsigned integer, possibly cropped.
  1022. constexpr uint16_t u16() const noexcept { return uint16_t(_data64 & 0xFFFFu);}
  1023. //! Returns immediate value as 32-bit signed integer, possibly cropped.
  1024. constexpr int32_t i32() const noexcept { return int32_t(_data64 & 0xFFFFFFFFu); }
  1025. //! Returns low 32-bit signed integer.
  1026. constexpr int32_t i32Lo() const noexcept { return int32_t(_data64 & 0xFFFFFFFFu); }
  1027. //! Returns high 32-bit signed integer.
  1028. constexpr int32_t i32Hi() const noexcept { return int32_t(_data64 >> 32); }
  1029. //! Returns immediate value as 32-bit unsigned integer, possibly cropped.
  1030. constexpr uint32_t u32() const noexcept { return uint32_t(_data64 & 0xFFFFFFFFu); }
  1031. //! Returns low 32-bit signed integer.
  1032. constexpr uint32_t u32Lo() const noexcept { return uint32_t(_data64 & 0xFFFFFFFFu); }
  1033. //! Returns high 32-bit signed integer.
  1034. constexpr uint32_t u32Hi() const noexcept { return uint32_t(_data64 >> 32); }
  1035. //! Returns immediate value as 64-bit signed integer.
  1036. constexpr int64_t i64() const noexcept { return int64_t(_data64); }
  1037. //! Returns immediate value as 64-bit unsigned integer.
  1038. constexpr uint64_t u64() const noexcept { return _data64; }
  1039. //! Returns immediate value as `intptr_t`, possibly cropped if size of `intptr_t` is 32 bits.
  1040. constexpr intptr_t iptr() const noexcept { return (sizeof(intptr_t) == sizeof(int64_t)) ? intptr_t(_data64) : intptr_t(i32()); }
  1041. //! Returns immediate value as `uintptr_t`, possibly cropped if size of `uintptr_t` is 32 bits.
  1042. constexpr uintptr_t uptr() const noexcept { return (sizeof(uintptr_t) == sizeof(uint64_t)) ? uintptr_t(_data64) : uintptr_t(u32()); }
  1043. //! Sets immediate value to 8-bit signed integer `val`.
  1044. inline void setI8(int8_t val) noexcept { _data64 = uint64_t(int64_t(val)); }
  1045. //! Sets immediate value to 8-bit unsigned integer `val`.
  1046. inline void setU8(uint8_t val) noexcept { _data64 = uint64_t(val); }
  1047. //! Sets immediate value to 16-bit signed integer `val`.
  1048. inline void setI16(int16_t val) noexcept { _data64 = uint64_t(int64_t(val)); }
  1049. //! Sets immediate value to 16-bit unsigned integer `val`.
  1050. inline void setU16(uint16_t val) noexcept { _data64 = uint64_t(val); }
  1051. //! Sets immediate value to 32-bit signed integer `val`.
  1052. inline void setI32(int32_t val) noexcept { _data64 = uint64_t(int64_t(val)); }
  1053. //! Sets immediate value to 32-bit unsigned integer `val`.
  1054. inline void setU32(uint32_t val) noexcept { _data64 = uint64_t(val); }
  1055. //! Sets immediate value to 64-bit signed integer `val`.
  1056. inline void setI64(int64_t val) noexcept { _data64 = uint64_t(val); }
  1057. //! Sets immediate value to 64-bit unsigned integer `val`.
  1058. inline void setU64(uint64_t val) noexcept { _data64 = val; }
  1059. //! Sets immediate value to intptr_t `val`.
  1060. inline void setIPtr(intptr_t val) noexcept { _data64 = uint64_t(int64_t(val)); }
  1061. //! Sets immediate value to uintptr_t `val`.
  1062. inline void setUPtr(uintptr_t val) noexcept { _data64 = uint64_t(val); }
  1063. //! Sets immediate value to `val`.
  1064. template<typename T>
  1065. inline void setValue(T val) noexcept { setI64(int64_t(Support::asNormalized(val))); }
  1066. inline void setDouble(double d) noexcept {
  1067. _data64 = Support::bitCast<uint64_t>(d);
  1068. }
  1069. //! \}
  1070. //! \name Utilities
  1071. //! \{
  1072. //! Clones the immediate operand.
  1073. constexpr Imm clone() const noexcept { return Imm(*this); }
  1074. inline void signExtend8Bits() noexcept { _data64 = uint64_t(int64_t(i8())); }
  1075. inline void signExtend16Bits() noexcept { _data64 = uint64_t(int64_t(i16())); }
  1076. inline void signExtend32Bits() noexcept { _data64 = uint64_t(int64_t(i32())); }
  1077. inline void zeroExtend8Bits() noexcept { _data64 &= 0x000000FFu; }
  1078. inline void zeroExtend16Bits() noexcept { _data64 &= 0x0000FFFFu; }
  1079. inline void zeroExtend32Bits() noexcept { _data64 &= 0xFFFFFFFFu; }
  1080. //! \}
  1081. };
  1082. //! Creates a new immediate operand.
  1083. //!
  1084. //! Using `imm(x)` is much nicer than using `Imm(x)` as this is a template
  1085. //! which can accept any integer including pointers and function pointers.
  1086. template<typename T>
  1087. static constexpr Imm imm(T val) noexcept {
  1088. return Imm(std::is_signed<T>::value ? int64_t(val) : int64_t(uint64_t(val)));
  1089. }
  1090. //! \}
  1091. ASMJIT_END_NAMESPACE
  1092. #endif // _ASMJIT_CORE_OPERAND_H