1
0

x86operand.h 49 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043
  1. // [AsmJit]
  2. // Machine Code Generation for C++.
  3. //
  4. // [License]
  5. // Zlib - See LICENSE.md file in the package.
  6. #ifndef _ASMJIT_X86_OPERAND_H
  7. #define _ASMJIT_X86_OPERAND_H
  8. #include "../core/arch.h"
  9. #include "../core/operand.h"
  10. #include "../core/type.h"
  11. #include "../x86/x86globals.h"
  12. ASMJIT_BEGIN_SUB_NAMESPACE(x86)
  13. // ============================================================================
  14. // [Forward Declarations]
  15. // ============================================================================
  16. class Reg;
  17. class Mem;
  18. class Gp;
  19. class Gpb;
  20. class GpbLo;
  21. class GpbHi;
  22. class Gpw;
  23. class Gpd;
  24. class Gpq;
  25. class Vec;
  26. class Xmm;
  27. class Ymm;
  28. class Zmm;
  29. class Mm;
  30. class KReg;
  31. class SReg;
  32. class CReg;
  33. class DReg;
  34. class St;
  35. class Bnd;
  36. class Rip;
  37. //! \addtogroup asmjit_x86
  38. //! \{
  39. // ============================================================================
  40. // [asmjit::x86::RegTraits]
  41. // ============================================================================
  42. //! Register traits (X86).
  43. //!
  44. //! Register traits contains information about a particular register type. It's
  45. //! used by asmjit to setup register information on-the-fly and to populate
  46. //! tables that contain register information (this way it's possible to change
  47. //! register types and groups without having to reorder these tables).
  48. template<uint32_t REG_TYPE>
  49. struct RegTraits : public BaseRegTraits {};
  50. //! \cond
  51. // <--------------------+-----+-------------------------+------------------------+---+---+----------------+
  52. // | Reg | Reg-Type | Reg-Group |Sz |Cnt| TypeId |
  53. // <--------------------+-----+-------------------------+------------------------+---+---+----------------+
  54. ASMJIT_DEFINE_REG_TRAITS(GpbLo, BaseReg::kTypeGp8Lo , BaseReg::kGroupGp , 1 , 16, Type::kIdI8 );
  55. ASMJIT_DEFINE_REG_TRAITS(GpbHi, BaseReg::kTypeGp8Hi , BaseReg::kGroupGp , 1 , 4 , Type::kIdI8 );
  56. ASMJIT_DEFINE_REG_TRAITS(Gpw , BaseReg::kTypeGp16 , BaseReg::kGroupGp , 2 , 16, Type::kIdI16 );
  57. ASMJIT_DEFINE_REG_TRAITS(Gpd , BaseReg::kTypeGp32 , BaseReg::kGroupGp , 4 , 16, Type::kIdI32 );
  58. ASMJIT_DEFINE_REG_TRAITS(Gpq , BaseReg::kTypeGp64 , BaseReg::kGroupGp , 8 , 16, Type::kIdI64 );
  59. ASMJIT_DEFINE_REG_TRAITS(Xmm , BaseReg::kTypeVec128 , BaseReg::kGroupVec , 16, 32, Type::kIdI32x4 );
  60. ASMJIT_DEFINE_REG_TRAITS(Ymm , BaseReg::kTypeVec256 , BaseReg::kGroupVec , 32, 32, Type::kIdI32x8 );
  61. ASMJIT_DEFINE_REG_TRAITS(Zmm , BaseReg::kTypeVec512 , BaseReg::kGroupVec , 64, 32, Type::kIdI32x16);
  62. ASMJIT_DEFINE_REG_TRAITS(Mm , BaseReg::kTypeOther0 , BaseReg::kGroupOther0 , 8 , 8 , Type::kIdMmx64 );
  63. ASMJIT_DEFINE_REG_TRAITS(KReg , BaseReg::kTypeOther1 , BaseReg::kGroupOther1 , 0 , 8 , Type::kIdVoid );
  64. ASMJIT_DEFINE_REG_TRAITS(SReg , BaseReg::kTypeCustom + 0, BaseReg::kGroupVirt + 0, 2 , 7 , Type::kIdVoid );
  65. ASMJIT_DEFINE_REG_TRAITS(CReg , BaseReg::kTypeCustom + 1, BaseReg::kGroupVirt + 1, 0 , 16, Type::kIdVoid );
  66. ASMJIT_DEFINE_REG_TRAITS(DReg , BaseReg::kTypeCustom + 2, BaseReg::kGroupVirt + 2, 0 , 16, Type::kIdVoid );
  67. ASMJIT_DEFINE_REG_TRAITS(St , BaseReg::kTypeCustom + 3, BaseReg::kGroupVirt + 3, 10, 8 , Type::kIdF80 );
  68. ASMJIT_DEFINE_REG_TRAITS(Bnd , BaseReg::kTypeCustom + 4, BaseReg::kGroupVirt + 4, 16, 4 , Type::kIdVoid );
  69. ASMJIT_DEFINE_REG_TRAITS(Rip , BaseReg::kTypeIP , BaseReg::kGroupVirt + 5, 0 , 1 , Type::kIdVoid );
  70. //! \endcond
  71. // ============================================================================
  72. // [asmjit::x86::Reg]
  73. // ============================================================================
  74. //! Register (X86).
  75. class Reg : public BaseReg {
  76. public:
  77. ASMJIT_DEFINE_ABSTRACT_REG(Reg, BaseReg)
  78. //! Register type.
  79. enum RegType : uint32_t {
  80. kTypeNone = BaseReg::kTypeNone, //!< No register type or invalid register.
  81. kTypeGpbLo = BaseReg::kTypeGp8Lo, //!< Low GPB register (AL, BL, CL, DL, ...).
  82. kTypeGpbHi = BaseReg::kTypeGp8Hi, //!< High GPB register (AH, BH, CH, DH only).
  83. kTypeGpw = BaseReg::kTypeGp16, //!< GPW register.
  84. kTypeGpd = BaseReg::kTypeGp32, //!< GPD register.
  85. kTypeGpq = BaseReg::kTypeGp64, //!< GPQ register (64-bit).
  86. kTypeXmm = BaseReg::kTypeVec128, //!< XMM register (SSE+).
  87. kTypeYmm = BaseReg::kTypeVec256, //!< YMM register (AVX+).
  88. kTypeZmm = BaseReg::kTypeVec512, //!< ZMM register (AVX512+).
  89. kTypeMm = BaseReg::kTypeOther0, //!< MMX register.
  90. kTypeKReg = BaseReg::kTypeOther1, //!< K register (AVX512+).
  91. kTypeSReg = BaseReg::kTypeCustom+0, //!< Segment register (None, ES, CS, SS, DS, FS, GS).
  92. kTypeCReg = BaseReg::kTypeCustom+1, //!< Control register (CR).
  93. kTypeDReg = BaseReg::kTypeCustom+2, //!< Debug register (DR).
  94. kTypeSt = BaseReg::kTypeCustom+3, //!< FPU (x87) register.
  95. kTypeBnd = BaseReg::kTypeCustom+4, //!< Bound register (BND).
  96. kTypeRip = BaseReg::kTypeIP, //!< Instruction pointer (EIP, RIP).
  97. kTypeCount = BaseReg::kTypeCustom+5 //!< Count of register types.
  98. };
  99. //! Register group.
  100. enum RegGroup : uint32_t {
  101. kGroupGp = BaseReg::kGroupGp, //!< GP register group or none (universal).
  102. kGroupVec = BaseReg::kGroupVec, //!< XMM|YMM|ZMM register group (universal).
  103. kGroupMm = BaseReg::kGroupOther0, //!< MMX register group (legacy).
  104. kGroupKReg = BaseReg::kGroupOther1, //!< K register group.
  105. // These are not managed by BaseCompiler nor used by Func-API:
  106. kGroupSReg = BaseReg::kGroupVirt+0, //!< Segment register group.
  107. kGroupCReg = BaseReg::kGroupVirt+1, //!< Control register group.
  108. kGroupDReg = BaseReg::kGroupVirt+2, //!< Debug register group.
  109. kGroupSt = BaseReg::kGroupVirt+3, //!< FPU register group.
  110. kGroupBnd = BaseReg::kGroupVirt+4, //!< Bound register group.
  111. kGroupRip = BaseReg::kGroupVirt+5, //!< Instrucion pointer (IP).
  112. kGroupCount //!< Count of all register groups.
  113. };
  114. //! Tests whether the register is a GPB register (8-bit).
  115. constexpr bool isGpb() const noexcept { return size() == 1; }
  116. //! Tests whether the register is a low GPB register (8-bit).
  117. constexpr bool isGpbLo() const noexcept { return hasSignature(RegTraits<kTypeGpbLo>::kSignature); }
  118. //! Tests whether the register is a high GPB register (8-bit).
  119. constexpr bool isGpbHi() const noexcept { return hasSignature(RegTraits<kTypeGpbHi>::kSignature); }
  120. //! Tests whether the register is a GPW register (16-bit).
  121. constexpr bool isGpw() const noexcept { return hasSignature(RegTraits<kTypeGpw>::kSignature); }
  122. //! Tests whether the register is a GPD register (32-bit).
  123. constexpr bool isGpd() const noexcept { return hasSignature(RegTraits<kTypeGpd>::kSignature); }
  124. //! Tests whether the register is a GPQ register (64-bit).
  125. constexpr bool isGpq() const noexcept { return hasSignature(RegTraits<kTypeGpq>::kSignature); }
  126. //! Tests whether the register is an XMM register (128-bit).
  127. constexpr bool isXmm() const noexcept { return hasSignature(RegTraits<kTypeXmm>::kSignature); }
  128. //! Tests whether the register is a YMM register (256-bit).
  129. constexpr bool isYmm() const noexcept { return hasSignature(RegTraits<kTypeYmm>::kSignature); }
  130. //! Tests whether the register is a ZMM register (512-bit).
  131. constexpr bool isZmm() const noexcept { return hasSignature(RegTraits<kTypeZmm>::kSignature); }
  132. //! Tests whether the register is an MMX register (64-bit).
  133. constexpr bool isMm() const noexcept { return hasSignature(RegTraits<kTypeMm>::kSignature); }
  134. //! Tests whether the register is a K register (64-bit).
  135. constexpr bool isKReg() const noexcept { return hasSignature(RegTraits<kTypeKReg>::kSignature); }
  136. //! Tests whether the register is a segment register.
  137. constexpr bool isSReg() const noexcept { return hasSignature(RegTraits<kTypeSReg>::kSignature); }
  138. //! Tests whether the register is a control register.
  139. constexpr bool isCReg() const noexcept { return hasSignature(RegTraits<kTypeCReg>::kSignature); }
  140. //! Tests whether the register is a debug register.
  141. constexpr bool isDReg() const noexcept { return hasSignature(RegTraits<kTypeDReg>::kSignature); }
  142. //! Tests whether the register is an FPU register (80-bit).
  143. constexpr bool isSt() const noexcept { return hasSignature(RegTraits<kTypeSt>::kSignature); }
  144. //! Tests whether the register is a bound register.
  145. constexpr bool isBnd() const noexcept { return hasSignature(RegTraits<kTypeBnd>::kSignature); }
  146. //! Tests whether the register is RIP.
  147. constexpr bool isRip() const noexcept { return hasSignature(RegTraits<kTypeRip>::kSignature); }
  148. template<uint32_t REG_TYPE>
  149. inline void setRegT(uint32_t rId) noexcept {
  150. setSignature(RegTraits<REG_TYPE>::kSignature);
  151. setId(rId);
  152. }
  153. inline void setTypeAndId(uint32_t rType, uint32_t rId) noexcept {
  154. ASMJIT_ASSERT(rType < kTypeCount);
  155. setSignature(signatureOf(rType));
  156. setId(rId);
  157. }
  158. static inline uint32_t groupOf(uint32_t rType) noexcept;
  159. template<uint32_t REG_TYPE>
  160. static inline uint32_t groupOfT() noexcept { return RegTraits<REG_TYPE>::kGroup; }
  161. static inline uint32_t typeIdOf(uint32_t rType) noexcept;
  162. template<uint32_t REG_TYPE>
  163. static inline uint32_t typeIdOfT() noexcept { return RegTraits<REG_TYPE>::kTypeId; }
  164. static inline uint32_t signatureOf(uint32_t rType) noexcept;
  165. template<uint32_t REG_TYPE>
  166. static inline uint32_t signatureOfT() noexcept { return RegTraits<REG_TYPE>::kSignature; }
  167. static inline uint32_t signatureOfVecByType(uint32_t typeId) noexcept {
  168. return typeId <= Type::_kIdVec128End ? RegTraits<kTypeXmm>::kSignature :
  169. typeId <= Type::_kIdVec256End ? RegTraits<kTypeYmm>::kSignature : RegTraits<kTypeZmm>::kSignature;
  170. }
  171. static inline uint32_t signatureOfVecBySize(uint32_t size) noexcept {
  172. return size <= 16 ? RegTraits<kTypeXmm>::kSignature :
  173. size <= 32 ? RegTraits<kTypeYmm>::kSignature : RegTraits<kTypeZmm>::kSignature;
  174. }
  175. //! Tests whether the `op` operand is either a low or high 8-bit GPB register.
  176. static inline bool isGpb(const Operand_& op) noexcept {
  177. // Check operand type, register group, and size. Not interested in register type.
  178. const uint32_t kSgn = (Operand::kOpReg << kSignatureOpShift ) |
  179. (1 << kSignatureSizeShift) ;
  180. return (op.signature() & (kSignatureOpMask | kSignatureSizeMask)) == kSgn;
  181. }
  182. static inline bool isGpbLo(const Operand_& op) noexcept { return op.as<Reg>().isGpbLo(); }
  183. static inline bool isGpbHi(const Operand_& op) noexcept { return op.as<Reg>().isGpbHi(); }
  184. static inline bool isGpw(const Operand_& op) noexcept { return op.as<Reg>().isGpw(); }
  185. static inline bool isGpd(const Operand_& op) noexcept { return op.as<Reg>().isGpd(); }
  186. static inline bool isGpq(const Operand_& op) noexcept { return op.as<Reg>().isGpq(); }
  187. static inline bool isXmm(const Operand_& op) noexcept { return op.as<Reg>().isXmm(); }
  188. static inline bool isYmm(const Operand_& op) noexcept { return op.as<Reg>().isYmm(); }
  189. static inline bool isZmm(const Operand_& op) noexcept { return op.as<Reg>().isZmm(); }
  190. static inline bool isMm(const Operand_& op) noexcept { return op.as<Reg>().isMm(); }
  191. static inline bool isKReg(const Operand_& op) noexcept { return op.as<Reg>().isKReg(); }
  192. static inline bool isSReg(const Operand_& op) noexcept { return op.as<Reg>().isSReg(); }
  193. static inline bool isCReg(const Operand_& op) noexcept { return op.as<Reg>().isCReg(); }
  194. static inline bool isDReg(const Operand_& op) noexcept { return op.as<Reg>().isDReg(); }
  195. static inline bool isSt(const Operand_& op) noexcept { return op.as<Reg>().isSt(); }
  196. static inline bool isBnd(const Operand_& op) noexcept { return op.as<Reg>().isBnd(); }
  197. static inline bool isRip(const Operand_& op) noexcept { return op.as<Reg>().isRip(); }
  198. static inline bool isGpb(const Operand_& op, uint32_t rId) noexcept { return isGpb(op) & (op.id() == rId); }
  199. static inline bool isGpbLo(const Operand_& op, uint32_t rId) noexcept { return isGpbLo(op) & (op.id() == rId); }
  200. static inline bool isGpbHi(const Operand_& op, uint32_t rId) noexcept { return isGpbHi(op) & (op.id() == rId); }
  201. static inline bool isGpw(const Operand_& op, uint32_t rId) noexcept { return isGpw(op) & (op.id() == rId); }
  202. static inline bool isGpd(const Operand_& op, uint32_t rId) noexcept { return isGpd(op) & (op.id() == rId); }
  203. static inline bool isGpq(const Operand_& op, uint32_t rId) noexcept { return isGpq(op) & (op.id() == rId); }
  204. static inline bool isXmm(const Operand_& op, uint32_t rId) noexcept { return isXmm(op) & (op.id() == rId); }
  205. static inline bool isYmm(const Operand_& op, uint32_t rId) noexcept { return isYmm(op) & (op.id() == rId); }
  206. static inline bool isZmm(const Operand_& op, uint32_t rId) noexcept { return isZmm(op) & (op.id() == rId); }
  207. static inline bool isMm(const Operand_& op, uint32_t rId) noexcept { return isMm(op) & (op.id() == rId); }
  208. static inline bool isKReg(const Operand_& op, uint32_t rId) noexcept { return isKReg(op) & (op.id() == rId); }
  209. static inline bool isSReg(const Operand_& op, uint32_t rId) noexcept { return isSReg(op) & (op.id() == rId); }
  210. static inline bool isCReg(const Operand_& op, uint32_t rId) noexcept { return isCReg(op) & (op.id() == rId); }
  211. static inline bool isDReg(const Operand_& op, uint32_t rId) noexcept { return isDReg(op) & (op.id() == rId); }
  212. static inline bool isSt(const Operand_& op, uint32_t rId) noexcept { return isSt(op) & (op.id() == rId); }
  213. static inline bool isBnd(const Operand_& op, uint32_t rId) noexcept { return isBnd(op) & (op.id() == rId); }
  214. static inline bool isRip(const Operand_& op, uint32_t rId) noexcept { return isRip(op) & (op.id() == rId); }
  215. };
  216. //! General purpose register (X86).
  217. class Gp : public Reg {
  218. public:
  219. ASMJIT_DEFINE_ABSTRACT_REG(Gp, Reg)
  220. //! Physical id (X86).
  221. //!
  222. //! \note Register indexes have been reduced to only support general purpose
  223. //! registers. There is no need to have enumerations with number suffix that
  224. //! expands to the exactly same value as the suffix value itself.
  225. enum Id : uint32_t {
  226. kIdAx = 0, //!< Physical id of AL|AH|AX|EAX|RAX registers.
  227. kIdCx = 1, //!< Physical id of CL|CH|CX|ECX|RCX registers.
  228. kIdDx = 2, //!< Physical id of DL|DH|DX|EDX|RDX registers.
  229. kIdBx = 3, //!< Physical id of BL|BH|BX|EBX|RBX registers.
  230. kIdSp = 4, //!< Physical id of SPL|SP|ESP|RSP registers.
  231. kIdBp = 5, //!< Physical id of BPL|BP|EBP|RBP registers.
  232. kIdSi = 6, //!< Physical id of SIL|SI|ESI|RSI registers.
  233. kIdDi = 7, //!< Physical id of DIL|DI|EDI|RDI registers.
  234. kIdR8 = 8, //!< Physical id of R8B|R8W|R8D|R8 registers (64-bit only).
  235. kIdR9 = 9, //!< Physical id of R9B|R9W|R9D|R9 registers (64-bit only).
  236. kIdR10 = 10, //!< Physical id of R10B|R10W|R10D|R10 registers (64-bit only).
  237. kIdR11 = 11, //!< Physical id of R11B|R11W|R11D|R11 registers (64-bit only).
  238. kIdR12 = 12, //!< Physical id of R12B|R12W|R12D|R12 registers (64-bit only).
  239. kIdR13 = 13, //!< Physical id of R13B|R13W|R13D|R13 registers (64-bit only).
  240. kIdR14 = 14, //!< Physical id of R14B|R14W|R14D|R14 registers (64-bit only).
  241. kIdR15 = 15 //!< Physical id of R15B|R15W|R15D|R15 registers (64-bit only).
  242. };
  243. //! Casts this register to 8-bit (LO) part.
  244. inline GpbLo r8() const noexcept;
  245. //! Casts this register to 8-bit (LO) part.
  246. inline GpbLo r8Lo() const noexcept;
  247. //! Casts this register to 8-bit (HI) part.
  248. inline GpbHi r8Hi() const noexcept;
  249. //! Casts this register to 16-bit.
  250. inline Gpw r16() const noexcept;
  251. //! Casts this register to 32-bit.
  252. inline Gpd r32() const noexcept;
  253. //! Casts this register to 64-bit.
  254. inline Gpq r64() const noexcept;
  255. };
  256. //! Vector register (XMM|YMM|ZMM) (X86).
  257. class Vec : public Reg {
  258. ASMJIT_DEFINE_ABSTRACT_REG(Vec, Reg)
  259. //! Casts this register to XMM (clone).
  260. inline Xmm xmm() const noexcept;
  261. //! Casts this register to YMM.
  262. inline Ymm ymm() const noexcept;
  263. //! Casts this register to ZMM.
  264. inline Zmm zmm() const noexcept;
  265. //! Casts this register to a register that has half the size (or XMM if it's already XMM).
  266. inline Vec half() const noexcept {
  267. return Vec(type() == kTypeZmm ? signatureOf(kTypeYmm) : signatureOf(kTypeXmm), id());
  268. }
  269. };
  270. //! Segment register (X86).
  271. class SReg : public Reg {
  272. ASMJIT_DEFINE_FINAL_REG(SReg, Reg, RegTraits<kTypeSReg>)
  273. //! X86 segment id.
  274. enum Id : uint32_t {
  275. kIdNone = 0, //!< No segment (default).
  276. kIdEs = 1, //!< ES segment.
  277. kIdCs = 2, //!< CS segment.
  278. kIdSs = 3, //!< SS segment.
  279. kIdDs = 4, //!< DS segment.
  280. kIdFs = 5, //!< FS segment.
  281. kIdGs = 6, //!< GS segment.
  282. //! Count of segment registers supported by AsmJit.
  283. //!
  284. //! \note X86 architecture has 6 segment registers - ES, CS, SS, DS, FS, GS.
  285. //! X64 architecture lowers them down to just FS and GS. AsmJit supports 7
  286. //! segment registers - all addressable in both and X64 modes and one
  287. //! extra called `SReg::kIdNone`, which is AsmJit specific and means that
  288. //! there is no segment register specified.
  289. kIdCount = 7
  290. };
  291. };
  292. //! GPB low or high register (X86).
  293. class Gpb : public Gp { ASMJIT_DEFINE_ABSTRACT_REG(Gpb, Gp) };
  294. //! GPB low register (X86).
  295. class GpbLo : public Gpb { ASMJIT_DEFINE_FINAL_REG(GpbLo, Gpb, RegTraits<kTypeGpbLo>) };
  296. //! GPB high register (X86).
  297. class GpbHi : public Gpb { ASMJIT_DEFINE_FINAL_REG(GpbHi, Gpb, RegTraits<kTypeGpbHi>) };
  298. //! GPW register (X86).
  299. class Gpw : public Gp { ASMJIT_DEFINE_FINAL_REG(Gpw, Gp, RegTraits<kTypeGpw>) };
  300. //! GPD register (X86).
  301. class Gpd : public Gp { ASMJIT_DEFINE_FINAL_REG(Gpd, Gp, RegTraits<kTypeGpd>) };
  302. //! GPQ register (X86_64).
  303. class Gpq : public Gp { ASMJIT_DEFINE_FINAL_REG(Gpq, Gp, RegTraits<kTypeGpq>) };
  304. //! 128-bit XMM register (SSE+).
  305. class Xmm : public Vec {
  306. ASMJIT_DEFINE_FINAL_REG(Xmm, Vec, RegTraits<kTypeXmm>)
  307. //! Casts this register to a register that has half the size (XMM).
  308. inline Xmm half() const noexcept { return Xmm(id()); }
  309. };
  310. //! 256-bit YMM register (AVX+).
  311. class Ymm : public Vec {
  312. ASMJIT_DEFINE_FINAL_REG(Ymm, Vec, RegTraits<kTypeYmm>)
  313. //! Casts this register to a register that has half the size (XMM).
  314. inline Xmm half() const noexcept { return Xmm(id()); }
  315. };
  316. //! 512-bit ZMM register (AVX512+).
  317. class Zmm : public Vec {
  318. ASMJIT_DEFINE_FINAL_REG(Zmm, Vec, RegTraits<kTypeZmm>)
  319. //! Casts this register to a register that has half the size (YMM).
  320. inline Ymm half() const noexcept { return Ymm(id()); }
  321. };
  322. //! 64-bit MMX register (MMX+).
  323. class Mm : public Reg { ASMJIT_DEFINE_FINAL_REG(Mm, Reg, RegTraits<kTypeMm>) };
  324. //! 64-bit K register (AVX512+).
  325. class KReg : public Reg { ASMJIT_DEFINE_FINAL_REG(KReg, Reg, RegTraits<kTypeKReg>) };
  326. //! 32-bit or 64-bit control register (X86).
  327. class CReg : public Reg { ASMJIT_DEFINE_FINAL_REG(CReg, Reg, RegTraits<kTypeCReg>) };
  328. //! 32-bit or 64-bit debug register (X86).
  329. class DReg : public Reg { ASMJIT_DEFINE_FINAL_REG(DReg, Reg, RegTraits<kTypeDReg>) };
  330. //! 80-bit FPU register (X86).
  331. class St : public Reg { ASMJIT_DEFINE_FINAL_REG(St, Reg, RegTraits<kTypeSt>) };
  332. //! 128-bit BND register (BND+).
  333. class Bnd : public Reg { ASMJIT_DEFINE_FINAL_REG(Bnd, Reg, RegTraits<kTypeBnd>) };
  334. //! RIP register (X86).
  335. class Rip : public Reg { ASMJIT_DEFINE_FINAL_REG(Rip, Reg, RegTraits<kTypeRip>) };
  336. //! \cond
  337. inline GpbLo Gp::r8() const noexcept { return GpbLo(id()); }
  338. inline GpbLo Gp::r8Lo() const noexcept { return GpbLo(id()); }
  339. inline GpbHi Gp::r8Hi() const noexcept { return GpbHi(id()); }
  340. inline Gpw Gp::r16() const noexcept { return Gpw(id()); }
  341. inline Gpd Gp::r32() const noexcept { return Gpd(id()); }
  342. inline Gpq Gp::r64() const noexcept { return Gpq(id()); }
  343. inline Xmm Vec::xmm() const noexcept { return Xmm(*this, id()); }
  344. inline Ymm Vec::ymm() const noexcept { return Ymm(*this, id()); }
  345. inline Zmm Vec::zmm() const noexcept { return Zmm(*this, id()); }
  346. //! \endcond
  347. // ============================================================================
  348. // [asmjit::x86::Mem]
  349. // ============================================================================
  350. //! Memory operand.
  351. class Mem : public BaseMem {
  352. public:
  353. //! Additional bits of operand's signature used by `Mem`.
  354. enum AdditionalBits : uint32_t {
  355. kSignatureMemSegmentShift = 16,
  356. kSignatureMemSegmentMask = 0x07u << kSignatureMemSegmentShift,
  357. kSignatureMemShiftShift = 19,
  358. kSignatureMemShiftMask = 0x03u << kSignatureMemShiftShift,
  359. kSignatureMemBroadcastShift = 21,
  360. kSignatureMemBroadcastMask = 0x7u << kSignatureMemBroadcastShift
  361. };
  362. enum Broadcast : uint32_t {
  363. kBroadcast1To1 = 0,
  364. kBroadcast1To2 = 1,
  365. kBroadcast1To4 = 2,
  366. kBroadcast1To8 = 3,
  367. kBroadcast1To16 = 4,
  368. kBroadcast1To32 = 5,
  369. kBroadcast1To64 = 6
  370. };
  371. // --------------------------------------------------------------------------
  372. // [Construction / Destruction]
  373. // --------------------------------------------------------------------------
  374. //! Creates a default `Mem` operand that points to [0].
  375. constexpr Mem() noexcept
  376. : BaseMem() {}
  377. constexpr Mem(const Mem& other) noexcept
  378. : BaseMem(other) {}
  379. //! \cond INTERNAL
  380. //!
  381. //! A constructor used internally to create `Mem` operand from `Decomposed` data.
  382. constexpr explicit Mem(const Decomposed& d) noexcept
  383. : BaseMem(d) {}
  384. //! \endcond
  385. constexpr Mem(const Label& base, int32_t off, uint32_t size = 0, uint32_t flags = 0) noexcept
  386. : BaseMem(Decomposed { Label::kLabelTag, base.id(), 0, 0, off, size, flags }) {}
  387. constexpr Mem(const Label& base, const BaseReg& index, uint32_t shift, int32_t off, uint32_t size = 0, uint32_t flags = 0) noexcept
  388. : BaseMem(Decomposed { Label::kLabelTag, base.id(), index.type(), index.id(), off, size, flags | (shift << kSignatureMemShiftShift) }) {}
  389. constexpr Mem(const BaseReg& base, int32_t off, uint32_t size = 0, uint32_t flags = 0) noexcept
  390. : BaseMem(Decomposed { base.type(), base.id(), 0, 0, off, size, flags }) {}
  391. constexpr Mem(const BaseReg& base, const BaseReg& index, uint32_t shift, int32_t off, uint32_t size = 0, uint32_t flags = 0) noexcept
  392. : BaseMem(Decomposed { base.type(), base.id(), index.type(), index.id(), off, size, flags | (shift << kSignatureMemShiftShift) }) {}
  393. constexpr explicit Mem(uint64_t base, uint32_t size = 0, uint32_t flags = 0) noexcept
  394. : BaseMem(Decomposed { 0, uint32_t(base >> 32), 0, 0, int32_t(uint32_t(base & 0xFFFFFFFFu)), size, flags }) {}
  395. constexpr Mem(uint64_t base, const BaseReg& index, uint32_t shift = 0, uint32_t size = 0, uint32_t flags = 0) noexcept
  396. : BaseMem(Decomposed { 0, uint32_t(base >> 32), index.type(), index.id(), int32_t(uint32_t(base & 0xFFFFFFFFu)), size, flags | (shift << kSignatureMemShiftShift) }) {}
  397. constexpr Mem(Globals::Init_, uint32_t u0, uint32_t u1, uint32_t u2, uint32_t u3) noexcept
  398. : BaseMem(Globals::Init, u0, u1, u2, u3) {}
  399. inline explicit Mem(Globals::NoInit_) noexcept
  400. : BaseMem(Globals::NoInit) {}
  401. //! Clones the memory operand.
  402. constexpr Mem clone() const noexcept { return Mem(*this); }
  403. //! Creates a new copy of this memory operand adjusted by `off`.
  404. inline Mem cloneAdjusted(int64_t off) const noexcept {
  405. Mem result(*this);
  406. result.addOffset(off);
  407. return result;
  408. }
  409. //! Converts memory `baseType` and `baseId` to `x86::Reg` instance.
  410. //!
  411. //! The memory must have a valid base register otherwise the result will be wrong.
  412. inline Reg baseReg() const noexcept { return Reg::fromTypeAndId(baseType(), baseId()); }
  413. //! Converts memory `indexType` and `indexId` to `x86::Reg` instance.
  414. //!
  415. //! The memory must have a valid index register otherwise the result will be wrong.
  416. inline Reg indexReg() const noexcept { return Reg::fromTypeAndId(indexType(), indexId()); }
  417. constexpr Mem _1to1() const noexcept { return Mem(Globals::Init, (_signature & ~kSignatureMemBroadcastMask) | (kBroadcast1To1 << kSignatureMemBroadcastShift), _baseId, _data32[0], _data32[1]); }
  418. constexpr Mem _1to2() const noexcept { return Mem(Globals::Init, (_signature & ~kSignatureMemBroadcastMask) | (kBroadcast1To2 << kSignatureMemBroadcastShift), _baseId, _data32[0], _data32[1]); }
  419. constexpr Mem _1to4() const noexcept { return Mem(Globals::Init, (_signature & ~kSignatureMemBroadcastMask) | (kBroadcast1To4 << kSignatureMemBroadcastShift), _baseId, _data32[0], _data32[1]); }
  420. constexpr Mem _1to8() const noexcept { return Mem(Globals::Init, (_signature & ~kSignatureMemBroadcastMask) | (kBroadcast1To8 << kSignatureMemBroadcastShift), _baseId, _data32[0], _data32[1]); }
  421. constexpr Mem _1to16() const noexcept { return Mem(Globals::Init, (_signature & ~kSignatureMemBroadcastMask) | (kBroadcast1To16 << kSignatureMemBroadcastShift), _baseId, _data32[0], _data32[1]); }
  422. constexpr Mem _1to32() const noexcept { return Mem(Globals::Init, (_signature & ~kSignatureMemBroadcastMask) | (kBroadcast1To32 << kSignatureMemBroadcastShift), _baseId, _data32[0], _data32[1]); }
  423. constexpr Mem _1to64() const noexcept { return Mem(Globals::Init, (_signature & ~kSignatureMemBroadcastMask) | (kBroadcast1To64 << kSignatureMemBroadcastShift), _baseId, _data32[0], _data32[1]); }
  424. // --------------------------------------------------------------------------
  425. // [Mem]
  426. // --------------------------------------------------------------------------
  427. using BaseMem::setIndex;
  428. inline void setIndex(const BaseReg& index, uint32_t shift) noexcept {
  429. setIndex(index);
  430. setShift(shift);
  431. }
  432. //! Tests whether the memory operand has a segment override.
  433. constexpr bool hasSegment() const noexcept { return _hasSignaturePart<kSignatureMemSegmentMask>(); }
  434. //! Returns the associated segment override as `SReg` operand.
  435. constexpr SReg segment() const noexcept { return SReg(segmentId()); }
  436. //! Returns segment override register id, see `SReg::Id`.
  437. constexpr uint32_t segmentId() const noexcept { return _getSignaturePart<kSignatureMemSegmentMask>(); }
  438. //! Sets the segment override to `seg`.
  439. inline void setSegment(const SReg& seg) noexcept { setSegment(seg.id()); }
  440. //! Sets the segment override to `id`.
  441. inline void setSegment(uint32_t rId) noexcept { _setSignaturePart<kSignatureMemSegmentMask>(rId); }
  442. //! Resets the segment override.
  443. inline void resetSegment() noexcept { _setSignaturePart<kSignatureMemSegmentMask>(0); }
  444. //! Tests whether the memory operand has shift (aka scale) value.
  445. constexpr bool hasShift() const noexcept { return _hasSignaturePart<kSignatureMemShiftMask>(); }
  446. //! Returns the memory operand's shift (aka scale) value.
  447. constexpr uint32_t shift() const noexcept { return _getSignaturePart<kSignatureMemShiftMask>(); }
  448. //! Sets the memory operand's shift (aka scale) value.
  449. inline void setShift(uint32_t shift) noexcept { _setSignaturePart<kSignatureMemShiftMask>(shift); }
  450. //! Resets the memory operand's shift (aka scale) value to zero.
  451. inline void resetShift() noexcept { _setSignaturePart<kSignatureMemShiftMask>(0); }
  452. //! Tests whether the memory operand has broadcast {1tox}.
  453. constexpr bool hasBroadcast() const noexcept { return _hasSignaturePart<kSignatureMemBroadcastMask>(); }
  454. //! Returns the memory operand's broadcast.
  455. constexpr uint32_t getBroadcast() const noexcept { return _getSignaturePart<kSignatureMemBroadcastMask>(); }
  456. //! Sets the memory operand's broadcast.
  457. inline void setBroadcast(uint32_t bcst) noexcept { _setSignaturePart<kSignatureMemBroadcastMask>(bcst); }
  458. //! Resets the memory operand's broadcast to none.
  459. inline void resetBroadcast() noexcept { _setSignaturePart<kSignatureMemBroadcastMask>(0); }
  460. // --------------------------------------------------------------------------
  461. // [Operator Overload]
  462. // --------------------------------------------------------------------------
  463. inline Mem& operator=(const Mem& other) noexcept = default;
  464. };
  465. // ============================================================================
  466. // [asmjit::x86::OpData]
  467. // ============================================================================
  468. struct OpData {
  469. //! Information about all architecture registers.
  470. ArchRegs archRegs;
  471. };
  472. ASMJIT_VARAPI const OpData opData;
  473. //! \cond
  474. // ... Reg methods that require `opData`.
  475. inline uint32_t Reg::groupOf(uint32_t rType) noexcept {
  476. ASMJIT_ASSERT(rType <= BaseReg::kTypeMax);
  477. return opData.archRegs.regInfo[rType].group();
  478. }
  479. inline uint32_t Reg::typeIdOf(uint32_t rType) noexcept {
  480. ASMJIT_ASSERT(rType <= BaseReg::kTypeMax);
  481. return opData.archRegs.regTypeToTypeId[rType];
  482. }
  483. inline uint32_t Reg::signatureOf(uint32_t rType) noexcept {
  484. ASMJIT_ASSERT(rType <= BaseReg::kTypeMax);
  485. return opData.archRegs.regInfo[rType].signature();
  486. }
  487. //! \endcond
  488. // ============================================================================
  489. // [asmjit::x86::regs]
  490. // ============================================================================
  491. namespace regs {
  492. //! Creates an 8-bit low GPB register operand.
  493. static constexpr GpbLo gpb(uint32_t rId) noexcept { return GpbLo(rId); }
  494. //! Creates an 8-bit low GPB register operand.
  495. static constexpr GpbLo gpb_lo(uint32_t rId) noexcept { return GpbLo(rId); }
  496. //! Creates an 8-bit high GPB register operand.
  497. static constexpr GpbHi gpb_hi(uint32_t rId) noexcept { return GpbHi(rId); }
  498. //! Creates a 16-bit GPW register operand.
  499. static constexpr Gpw gpw(uint32_t rId) noexcept { return Gpw(rId); }
  500. //! Creates a 32-bit GPD register operand.
  501. static constexpr Gpd gpd(uint32_t rId) noexcept { return Gpd(rId); }
  502. //! Creates a 64-bit GPQ register operand (64-bit).
  503. static constexpr Gpq gpq(uint32_t rId) noexcept { return Gpq(rId); }
  504. //! Creates a 128-bit XMM register operand.
  505. static constexpr Xmm xmm(uint32_t rId) noexcept { return Xmm(rId); }
  506. //! Creates a 256-bit YMM register operand.
  507. static constexpr Ymm ymm(uint32_t rId) noexcept { return Ymm(rId); }
  508. //! Creates a 512-bit ZMM register operand.
  509. static constexpr Zmm zmm(uint32_t rId) noexcept { return Zmm(rId); }
  510. //! Creates a 64-bit Mm register operand.
  511. static constexpr Mm mm(uint32_t rId) noexcept { return Mm(rId); }
  512. //! Creates a 64-bit K register operand.
  513. static constexpr KReg k(uint32_t rId) noexcept { return KReg(rId); }
  514. //! Creates a 32-bit or 64-bit control register operand.
  515. static constexpr CReg cr(uint32_t rId) noexcept { return CReg(rId); }
  516. //! Creates a 32-bit or 64-bit debug register operand.
  517. static constexpr DReg dr(uint32_t rId) noexcept { return DReg(rId); }
  518. //! Creates an 80-bit st register operand.
  519. static constexpr St st(uint32_t rId) noexcept { return St(rId); }
  520. //! Creates a 128-bit bound register operand.
  521. static constexpr Bnd bnd(uint32_t rId) noexcept { return Bnd(rId); }
  522. static constexpr Gp al(GpbLo::kSignature, Gp::kIdAx);
  523. static constexpr Gp bl(GpbLo::kSignature, Gp::kIdBx);
  524. static constexpr Gp cl(GpbLo::kSignature, Gp::kIdCx);
  525. static constexpr Gp dl(GpbLo::kSignature, Gp::kIdDx);
  526. static constexpr Gp spl(GpbLo::kSignature, Gp::kIdSp);
  527. static constexpr Gp bpl(GpbLo::kSignature, Gp::kIdBp);
  528. static constexpr Gp sil(GpbLo::kSignature, Gp::kIdSi);
  529. static constexpr Gp dil(GpbLo::kSignature, Gp::kIdDi);
  530. static constexpr Gp r8b(GpbLo::kSignature, Gp::kIdR8);
  531. static constexpr Gp r9b(GpbLo::kSignature, Gp::kIdR9);
  532. static constexpr Gp r10b(GpbLo::kSignature, Gp::kIdR10);
  533. static constexpr Gp r11b(GpbLo::kSignature, Gp::kIdR11);
  534. static constexpr Gp r12b(GpbLo::kSignature, Gp::kIdR12);
  535. static constexpr Gp r13b(GpbLo::kSignature, Gp::kIdR13);
  536. static constexpr Gp r14b(GpbLo::kSignature, Gp::kIdR14);
  537. static constexpr Gp r15b(GpbLo::kSignature, Gp::kIdR15);
  538. static constexpr Gp ah(GpbHi::kSignature, Gp::kIdAx);
  539. static constexpr Gp bh(GpbHi::kSignature, Gp::kIdBx);
  540. static constexpr Gp ch(GpbHi::kSignature, Gp::kIdCx);
  541. static constexpr Gp dh(GpbHi::kSignature, Gp::kIdDx);
  542. static constexpr Gp ax(Gpw::kSignature, Gp::kIdAx);
  543. static constexpr Gp bx(Gpw::kSignature, Gp::kIdBx);
  544. static constexpr Gp cx(Gpw::kSignature, Gp::kIdCx);
  545. static constexpr Gp dx(Gpw::kSignature, Gp::kIdDx);
  546. static constexpr Gp sp(Gpw::kSignature, Gp::kIdSp);
  547. static constexpr Gp bp(Gpw::kSignature, Gp::kIdBp);
  548. static constexpr Gp si(Gpw::kSignature, Gp::kIdSi);
  549. static constexpr Gp di(Gpw::kSignature, Gp::kIdDi);
  550. static constexpr Gp r8w(Gpw::kSignature, Gp::kIdR8);
  551. static constexpr Gp r9w(Gpw::kSignature, Gp::kIdR9);
  552. static constexpr Gp r10w(Gpw::kSignature, Gp::kIdR10);
  553. static constexpr Gp r11w(Gpw::kSignature, Gp::kIdR11);
  554. static constexpr Gp r12w(Gpw::kSignature, Gp::kIdR12);
  555. static constexpr Gp r13w(Gpw::kSignature, Gp::kIdR13);
  556. static constexpr Gp r14w(Gpw::kSignature, Gp::kIdR14);
  557. static constexpr Gp r15w(Gpw::kSignature, Gp::kIdR15);
  558. static constexpr Gp eax(Gpd::kSignature, Gp::kIdAx);
  559. static constexpr Gp ebx(Gpd::kSignature, Gp::kIdBx);
  560. static constexpr Gp ecx(Gpd::kSignature, Gp::kIdCx);
  561. static constexpr Gp edx(Gpd::kSignature, Gp::kIdDx);
  562. static constexpr Gp esp(Gpd::kSignature, Gp::kIdSp);
  563. static constexpr Gp ebp(Gpd::kSignature, Gp::kIdBp);
  564. static constexpr Gp esi(Gpd::kSignature, Gp::kIdSi);
  565. static constexpr Gp edi(Gpd::kSignature, Gp::kIdDi);
  566. static constexpr Gp r8d(Gpd::kSignature, Gp::kIdR8);
  567. static constexpr Gp r9d(Gpd::kSignature, Gp::kIdR9);
  568. static constexpr Gp r10d(Gpd::kSignature, Gp::kIdR10);
  569. static constexpr Gp r11d(Gpd::kSignature, Gp::kIdR11);
  570. static constexpr Gp r12d(Gpd::kSignature, Gp::kIdR12);
  571. static constexpr Gp r13d(Gpd::kSignature, Gp::kIdR13);
  572. static constexpr Gp r14d(Gpd::kSignature, Gp::kIdR14);
  573. static constexpr Gp r15d(Gpd::kSignature, Gp::kIdR15);
  574. static constexpr Gp rax(Gpq::kSignature, Gp::kIdAx);
  575. static constexpr Gp rbx(Gpq::kSignature, Gp::kIdBx);
  576. static constexpr Gp rcx(Gpq::kSignature, Gp::kIdCx);
  577. static constexpr Gp rdx(Gpq::kSignature, Gp::kIdDx);
  578. static constexpr Gp rsp(Gpq::kSignature, Gp::kIdSp);
  579. static constexpr Gp rbp(Gpq::kSignature, Gp::kIdBp);
  580. static constexpr Gp rsi(Gpq::kSignature, Gp::kIdSi);
  581. static constexpr Gp rdi(Gpq::kSignature, Gp::kIdDi);
  582. static constexpr Gp r8(Gpq::kSignature, Gp::kIdR8);
  583. static constexpr Gp r9(Gpq::kSignature, Gp::kIdR9);
  584. static constexpr Gp r10(Gpq::kSignature, Gp::kIdR10);
  585. static constexpr Gp r11(Gpq::kSignature, Gp::kIdR11);
  586. static constexpr Gp r12(Gpq::kSignature, Gp::kIdR12);
  587. static constexpr Gp r13(Gpq::kSignature, Gp::kIdR13);
  588. static constexpr Gp r14(Gpq::kSignature, Gp::kIdR14);
  589. static constexpr Gp r15(Gpq::kSignature, Gp::kIdR15);
  590. static constexpr Xmm xmm0(0);
  591. static constexpr Xmm xmm1(1);
  592. static constexpr Xmm xmm2(2);
  593. static constexpr Xmm xmm3(3);
  594. static constexpr Xmm xmm4(4);
  595. static constexpr Xmm xmm5(5);
  596. static constexpr Xmm xmm6(6);
  597. static constexpr Xmm xmm7(7);
  598. static constexpr Xmm xmm8(8);
  599. static constexpr Xmm xmm9(9);
  600. static constexpr Xmm xmm10(10);
  601. static constexpr Xmm xmm11(11);
  602. static constexpr Xmm xmm12(12);
  603. static constexpr Xmm xmm13(13);
  604. static constexpr Xmm xmm14(14);
  605. static constexpr Xmm xmm15(15);
  606. static constexpr Xmm xmm16(16);
  607. static constexpr Xmm xmm17(17);
  608. static constexpr Xmm xmm18(18);
  609. static constexpr Xmm xmm19(19);
  610. static constexpr Xmm xmm20(20);
  611. static constexpr Xmm xmm21(21);
  612. static constexpr Xmm xmm22(22);
  613. static constexpr Xmm xmm23(23);
  614. static constexpr Xmm xmm24(24);
  615. static constexpr Xmm xmm25(25);
  616. static constexpr Xmm xmm26(26);
  617. static constexpr Xmm xmm27(27);
  618. static constexpr Xmm xmm28(28);
  619. static constexpr Xmm xmm29(29);
  620. static constexpr Xmm xmm30(30);
  621. static constexpr Xmm xmm31(31);
  622. static constexpr Ymm ymm0(0);
  623. static constexpr Ymm ymm1(1);
  624. static constexpr Ymm ymm2(2);
  625. static constexpr Ymm ymm3(3);
  626. static constexpr Ymm ymm4(4);
  627. static constexpr Ymm ymm5(5);
  628. static constexpr Ymm ymm6(6);
  629. static constexpr Ymm ymm7(7);
  630. static constexpr Ymm ymm8(8);
  631. static constexpr Ymm ymm9(9);
  632. static constexpr Ymm ymm10(10);
  633. static constexpr Ymm ymm11(11);
  634. static constexpr Ymm ymm12(12);
  635. static constexpr Ymm ymm13(13);
  636. static constexpr Ymm ymm14(14);
  637. static constexpr Ymm ymm15(15);
  638. static constexpr Ymm ymm16(16);
  639. static constexpr Ymm ymm17(17);
  640. static constexpr Ymm ymm18(18);
  641. static constexpr Ymm ymm19(19);
  642. static constexpr Ymm ymm20(20);
  643. static constexpr Ymm ymm21(21);
  644. static constexpr Ymm ymm22(22);
  645. static constexpr Ymm ymm23(23);
  646. static constexpr Ymm ymm24(24);
  647. static constexpr Ymm ymm25(25);
  648. static constexpr Ymm ymm26(26);
  649. static constexpr Ymm ymm27(27);
  650. static constexpr Ymm ymm28(28);
  651. static constexpr Ymm ymm29(29);
  652. static constexpr Ymm ymm30(30);
  653. static constexpr Ymm ymm31(31);
  654. static constexpr Zmm zmm0(0);
  655. static constexpr Zmm zmm1(1);
  656. static constexpr Zmm zmm2(2);
  657. static constexpr Zmm zmm3(3);
  658. static constexpr Zmm zmm4(4);
  659. static constexpr Zmm zmm5(5);
  660. static constexpr Zmm zmm6(6);
  661. static constexpr Zmm zmm7(7);
  662. static constexpr Zmm zmm8(8);
  663. static constexpr Zmm zmm9(9);
  664. static constexpr Zmm zmm10(10);
  665. static constexpr Zmm zmm11(11);
  666. static constexpr Zmm zmm12(12);
  667. static constexpr Zmm zmm13(13);
  668. static constexpr Zmm zmm14(14);
  669. static constexpr Zmm zmm15(15);
  670. static constexpr Zmm zmm16(16);
  671. static constexpr Zmm zmm17(17);
  672. static constexpr Zmm zmm18(18);
  673. static constexpr Zmm zmm19(19);
  674. static constexpr Zmm zmm20(20);
  675. static constexpr Zmm zmm21(21);
  676. static constexpr Zmm zmm22(22);
  677. static constexpr Zmm zmm23(23);
  678. static constexpr Zmm zmm24(24);
  679. static constexpr Zmm zmm25(25);
  680. static constexpr Zmm zmm26(26);
  681. static constexpr Zmm zmm27(27);
  682. static constexpr Zmm zmm28(28);
  683. static constexpr Zmm zmm29(29);
  684. static constexpr Zmm zmm30(30);
  685. static constexpr Zmm zmm31(31);
  686. static constexpr Mm mm0(0);
  687. static constexpr Mm mm1(1);
  688. static constexpr Mm mm2(2);
  689. static constexpr Mm mm3(3);
  690. static constexpr Mm mm4(4);
  691. static constexpr Mm mm5(5);
  692. static constexpr Mm mm6(6);
  693. static constexpr Mm mm7(7);
  694. static constexpr KReg k0(0);
  695. static constexpr KReg k1(1);
  696. static constexpr KReg k2(2);
  697. static constexpr KReg k3(3);
  698. static constexpr KReg k4(4);
  699. static constexpr KReg k5(5);
  700. static constexpr KReg k6(6);
  701. static constexpr KReg k7(7);
  702. static constexpr SReg no_seg(SReg::kIdNone);
  703. static constexpr SReg es(SReg::kIdEs);
  704. static constexpr SReg cs(SReg::kIdCs);
  705. static constexpr SReg ss(SReg::kIdSs);
  706. static constexpr SReg ds(SReg::kIdDs);
  707. static constexpr SReg fs(SReg::kIdFs);
  708. static constexpr SReg gs(SReg::kIdGs);
  709. static constexpr CReg cr0(0);
  710. static constexpr CReg cr1(1);
  711. static constexpr CReg cr2(2);
  712. static constexpr CReg cr3(3);
  713. static constexpr CReg cr4(4);
  714. static constexpr CReg cr5(5);
  715. static constexpr CReg cr6(6);
  716. static constexpr CReg cr7(7);
  717. static constexpr CReg cr8(8);
  718. static constexpr CReg cr9(9);
  719. static constexpr CReg cr10(10);
  720. static constexpr CReg cr11(11);
  721. static constexpr CReg cr12(12);
  722. static constexpr CReg cr13(13);
  723. static constexpr CReg cr14(14);
  724. static constexpr CReg cr15(15);
  725. static constexpr DReg dr0(0);
  726. static constexpr DReg dr1(1);
  727. static constexpr DReg dr2(2);
  728. static constexpr DReg dr3(3);
  729. static constexpr DReg dr4(4);
  730. static constexpr DReg dr5(5);
  731. static constexpr DReg dr6(6);
  732. static constexpr DReg dr7(7);
  733. static constexpr DReg dr8(8);
  734. static constexpr DReg dr9(9);
  735. static constexpr DReg dr10(10);
  736. static constexpr DReg dr11(11);
  737. static constexpr DReg dr12(12);
  738. static constexpr DReg dr13(13);
  739. static constexpr DReg dr14(14);
  740. static constexpr DReg dr15(15);
  741. static constexpr St st0(0);
  742. static constexpr St st1(1);
  743. static constexpr St st2(2);
  744. static constexpr St st3(3);
  745. static constexpr St st4(4);
  746. static constexpr St st5(5);
  747. static constexpr St st6(6);
  748. static constexpr St st7(7);
  749. static constexpr Bnd bnd0(0);
  750. static constexpr Bnd bnd1(1);
  751. static constexpr Bnd bnd2(2);
  752. static constexpr Bnd bnd3(3);
  753. static constexpr Rip rip(0);
  754. } // {regs}
  755. // Make `x86::regs` accessible through `x86` namespace as well.
  756. using namespace regs;
  757. // ============================================================================
  758. // [asmjit::x86::ptr]
  759. // ============================================================================
  760. //! Creates `[base.reg + offset]` memory operand.
  761. static constexpr Mem ptr(const Gp& base, int32_t offset = 0, uint32_t size = 0) noexcept {
  762. return Mem(base, offset, size);
  763. }
  764. //! Creates `[base.reg + (index << shift) + offset]` memory operand (scalar index).
  765. static constexpr Mem ptr(const Gp& base, const Gp& index, uint32_t shift = 0, int32_t offset = 0, uint32_t size = 0) noexcept {
  766. return Mem(base, index, shift, offset, size);
  767. }
  768. //! Creates `[base.reg + (index << shift) + offset]` memory operand (vector index).
  769. static constexpr Mem ptr(const Gp& base, const Vec& index, uint32_t shift = 0, int32_t offset = 0, uint32_t size = 0) noexcept {
  770. return Mem(base, index, shift, offset, size);
  771. }
  772. //! Creates `[base + offset]` memory operand.
  773. static constexpr Mem ptr(const Label& base, int32_t offset = 0, uint32_t size = 0) noexcept {
  774. return Mem(base, offset, size);
  775. }
  776. //! Creates `[base + (index << shift) + offset]` memory operand.
  777. static constexpr Mem ptr(const Label& base, const Gp& index, uint32_t shift = 0, int32_t offset = 0, uint32_t size = 0) noexcept {
  778. return Mem(base, index, shift, offset, size);
  779. }
  780. //! Creates `[base + (index << shift) + offset]` memory operand.
  781. static constexpr Mem ptr(const Label& base, const Vec& index, uint32_t shift = 0, int32_t offset = 0, uint32_t size = 0) noexcept {
  782. return Mem(base, index, shift, offset, size);
  783. }
  784. //! Creates `[rip + offset]` memory operand.
  785. static constexpr Mem ptr(const Rip& rip_, int32_t offset = 0, uint32_t size = 0) noexcept {
  786. return Mem(rip_, offset, size);
  787. }
  788. //! Creates `[base]` absolute memory operand.
  789. static constexpr Mem ptr(uint64_t base, uint32_t size = 0) noexcept {
  790. return Mem(base, size);
  791. }
  792. //! Creates `[base + (index.reg << shift)]` absolute memory operand.
  793. static constexpr Mem ptr(uint64_t base, const Reg& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
  794. return Mem(base, index, shift, size);
  795. }
  796. //! Creates `[base + (index.reg << shift)]` absolute memory operand.
  797. static constexpr Mem ptr(uint64_t base, const Vec& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
  798. return Mem(base, index, shift, size);
  799. }
  800. //! Creates `[base]` absolute memory operand (absolute).
  801. static constexpr Mem ptr_abs(uint64_t base, uint32_t size = 0) noexcept {
  802. return Mem(base, size, BaseMem::kSignatureMemAbs);
  803. }
  804. //! Creates `[base + (index.reg << shift)]` absolute memory operand (absolute).
  805. static constexpr Mem ptr_abs(uint64_t base, const Reg& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
  806. return Mem(base, index, shift, size, BaseMem::kSignatureMemAbs);
  807. }
  808. //! Creates `[base + (index.reg << shift)]` absolute memory operand (absolute).
  809. static constexpr Mem ptr_abs(uint64_t base, const Vec& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
  810. return Mem(base, index, shift, size, BaseMem::kSignatureMemAbs);
  811. }
  812. //! Creates `[base]` relative memory operand (relative).
  813. static constexpr Mem ptr_rel(uint64_t base, uint32_t size = 0) noexcept {
  814. return Mem(base, size, BaseMem::kSignatureMemRel);
  815. }
  816. //! Creates `[base + (index.reg << shift)]` relative memory operand (relative).
  817. static constexpr Mem ptr_rel(uint64_t base, const Reg& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
  818. return Mem(base, index, shift, size, BaseMem::kSignatureMemRel);
  819. }
  820. //! Creates `[base + (index.reg << shift)]` relative memory operand (relative).
  821. static constexpr Mem ptr_rel(uint64_t base, const Vec& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
  822. return Mem(base, index, shift, size, BaseMem::kSignatureMemRel);
  823. }
  824. #define ASMJIT_MEM_PTR(FUNC, SIZE) \
  825. /*! Creates `[base + offset]` memory operand. */ \
  826. static constexpr Mem FUNC(const Gp& base, int32_t offset = 0) noexcept { \
  827. return Mem(base, offset, SIZE); \
  828. } \
  829. /*! Creates `[base + (index << shift) + offset]` memory operand. */ \
  830. static constexpr Mem FUNC(const Gp& base, const Gp& index, uint32_t shift = 0, int32_t offset = 0) noexcept { \
  831. return Mem(base, index, shift, offset, SIZE); \
  832. } \
  833. /*! Creates `[base + (vec_index << shift) + offset]` memory operand. */ \
  834. static constexpr Mem FUNC(const Gp& base, const Vec& index, uint32_t shift = 0, int32_t offset = 0) noexcept { \
  835. return Mem(base, index, shift, offset, SIZE); \
  836. } \
  837. /*! Creates `[base + offset]` memory operand. */ \
  838. static constexpr Mem FUNC(const Label& base, int32_t offset = 0) noexcept { \
  839. return Mem(base, offset, SIZE); \
  840. } \
  841. /*! Creates `[base + (index << shift) + offset]` memory operand. */ \
  842. static constexpr Mem FUNC(const Label& base, const Gp& index, uint32_t shift = 0, int32_t offset = 0) noexcept { \
  843. return Mem(base, index, shift, offset, SIZE); \
  844. } \
  845. /*! Creates `[rip + offset]` memory operand. */ \
  846. static constexpr Mem FUNC(const Rip& rip_, int32_t offset = 0) noexcept { \
  847. return Mem(rip_, offset, SIZE); \
  848. } \
  849. /*! Creates `[ptr]` memory operand. */ \
  850. static constexpr Mem FUNC(uint64_t base) noexcept { \
  851. return Mem(base, SIZE); \
  852. } \
  853. /*! Creates `[base + (index << shift) + offset]` memory operand. */ \
  854. static constexpr Mem FUNC(uint64_t base, const Gp& index, uint32_t shift = 0) noexcept { \
  855. return Mem(base, index, shift, SIZE); \
  856. } \
  857. /*! Creates `[base + (vec_index << shift) + offset]` memory operand. */ \
  858. static constexpr Mem FUNC(uint64_t base, const Vec& index, uint32_t shift = 0) noexcept { \
  859. return Mem(base, index, shift, SIZE); \
  860. } \
  861. \
  862. /*! Creates `[base + offset]` memory operand (absolute). */ \
  863. static constexpr Mem FUNC##_abs(uint64_t base) noexcept { \
  864. return Mem(base, SIZE, BaseMem::kSignatureMemAbs); \
  865. } \
  866. /*! Creates `[base + (index << shift) + offset]` memory operand (absolute). */ \
  867. static constexpr Mem FUNC##_abs(uint64_t base, const Gp& index, uint32_t shift = 0) noexcept { \
  868. return Mem(base, index, shift, SIZE, BaseMem::kSignatureMemAbs); \
  869. } \
  870. /*! Creates `[base + (vec_index << shift) + offset]` memory operand (absolute). */ \
  871. static constexpr Mem FUNC##_abs(uint64_t base, const Vec& index, uint32_t shift = 0) noexcept { \
  872. return Mem(base, index, shift, SIZE, BaseMem::kSignatureMemAbs); \
  873. } \
  874. \
  875. /*! Creates `[base + offset]` memory operand (relative). */ \
  876. static constexpr Mem FUNC##_rel(uint64_t base) noexcept { \
  877. return Mem(base, SIZE, BaseMem::kSignatureMemRel); \
  878. } \
  879. /*! Creates `[base + (index << shift) + offset]` memory operand (relative). */ \
  880. static constexpr Mem FUNC##_rel(uint64_t base, const Gp& index, uint32_t shift = 0) noexcept { \
  881. return Mem(base, index, shift, SIZE, BaseMem::kSignatureMemRel); \
  882. } \
  883. /*! Creates `[base + (vec_index << shift) + offset]` memory operand (relative). */ \
  884. static constexpr Mem FUNC##_rel(uint64_t base, const Vec& index, uint32_t shift = 0) noexcept { \
  885. return Mem(base, index, shift, SIZE, BaseMem::kSignatureMemRel); \
  886. }
  887. // Definition of memory operand constructors that use platform independent naming.
  888. ASMJIT_MEM_PTR(ptr_8, 1)
  889. ASMJIT_MEM_PTR(ptr_16, 2)
  890. ASMJIT_MEM_PTR(ptr_32, 4)
  891. ASMJIT_MEM_PTR(ptr_48, 6)
  892. ASMJIT_MEM_PTR(ptr_64, 8)
  893. ASMJIT_MEM_PTR(ptr_80, 10)
  894. ASMJIT_MEM_PTR(ptr_128, 16)
  895. ASMJIT_MEM_PTR(ptr_256, 32)
  896. ASMJIT_MEM_PTR(ptr_512, 64)
  897. // Definition of memory operand constructors that use X86-specific convention.
  898. ASMJIT_MEM_PTR(byte_ptr, 1)
  899. ASMJIT_MEM_PTR(word_ptr, 2)
  900. ASMJIT_MEM_PTR(dword_ptr, 4)
  901. ASMJIT_MEM_PTR(qword_ptr, 8)
  902. ASMJIT_MEM_PTR(tword_ptr, 10)
  903. ASMJIT_MEM_PTR(oword_ptr, 16)
  904. ASMJIT_MEM_PTR(dqword_ptr, 16)
  905. ASMJIT_MEM_PTR(qqword_ptr, 32)
  906. ASMJIT_MEM_PTR(xmmword_ptr, 16)
  907. ASMJIT_MEM_PTR(ymmword_ptr, 32)
  908. ASMJIT_MEM_PTR(zmmword_ptr, 64)
  909. #undef ASMJIT_MEM_PTR
  910. //! \}
  911. ASMJIT_END_SUB_NAMESPACE
  912. // ============================================================================
  913. // [asmjit::Type::IdOfT<x86::Reg>]
  914. // ============================================================================
  915. //! \cond INTERNAL
  916. ASMJIT_BEGIN_NAMESPACE
  917. ASMJIT_DEFINE_TYPE_ID(x86::Gpb, kIdI8);
  918. ASMJIT_DEFINE_TYPE_ID(x86::Gpw, kIdI16);
  919. ASMJIT_DEFINE_TYPE_ID(x86::Gpd, kIdI32);
  920. ASMJIT_DEFINE_TYPE_ID(x86::Gpq, kIdI64);
  921. ASMJIT_DEFINE_TYPE_ID(x86::Mm , kIdMmx64);
  922. ASMJIT_DEFINE_TYPE_ID(x86::Xmm, kIdI32x4);
  923. ASMJIT_DEFINE_TYPE_ID(x86::Ymm, kIdI32x8);
  924. ASMJIT_DEFINE_TYPE_ID(x86::Zmm, kIdI32x16);
  925. ASMJIT_END_NAMESPACE
  926. //! \endcond
  927. #endif // _ASMJIT_X86_OPERAND_H