1 // AsmJit - Machine code generation for C++
2 //
3 //  * Official AsmJit Home Page: https://asmjit.com
4 //  * Official Github Repository: https://github.com/asmjit/asmjit
5 //
6 // Copyright (c) 2008-2020 The AsmJit Authors
7 //
8 // This software is provided 'as-is', without any express or implied
9 // warranty. In no event will the authors be held liable for any damages
10 // arising from the use of this software.
11 //
12 // Permission is granted to anyone to use this software for any purpose,
13 // including commercial applications, and to alter it and redistribute it
14 // freely, subject to the following restrictions:
15 //
16 // 1. The origin of this software must not be misrepresented; you must not
17 //    claim that you wrote the original software. If you use this software
18 //    in a product, an acknowledgment in the product documentation would be
19 //    appreciated but is not required.
20 // 2. Altered source versions must be plainly marked as such, and must not be
21 //    misrepresented as being the original software.
22 // 3. This notice may not be removed or altered from any source distribution.
23 
24 #ifndef ASMJIT_CORE_ENVIRONMENT_H_INCLUDED
25 #define ASMJIT_CORE_ENVIRONMENT_H_INCLUDED
26 
27 #include "../core/globals.h"
28 
29 #if defined(__APPLE__)
30   #include <TargetConditionals.h>
31 #endif
32 
33 ASMJIT_BEGIN_NAMESPACE
34 
35 //! \addtogroup asmjit_core
36 //! \{
37 
38 // ============================================================================
39 // [asmjit::Environment]
40 // ============================================================================
41 
42 //! Represents an environment, which is usually related to a \ref Target.
43 //!
44 //! Environment has usually an 'arch-subarch-vendor-os-abi' format, which is
45 //! sometimes called "Triple" (historically it used to be 3 only parts) or
46 //! "Tuple", which is a convention used by Debian Linux.
47 //!
48 //! AsmJit doesn't support all possible combinations or architectures and ABIs,
49 //! however, it models the environment similarly to other compilers for future
50 //! extensibility.
51 class Environment {
52 public:
53   //! Architecture type, see \ref Arch.
54   uint8_t _arch;
55   //! Sub-architecture type, see \ref SubArch.
56   uint8_t _subArch;
57   //! Vendor type, see \ref Vendor.
58   uint8_t _vendor;
59   //! Platform type, see \ref Platform.
60   uint8_t _platform;
61   //! ABI type, see \ref Abi.
62   uint8_t _abi;
63   //! Object format, see \ref Format.
64   uint8_t _format;
65   //! Reserved for future use, must be zero.
66   uint16_t _reserved;
67 
68   //! Architecture.
69   enum Arch : uint32_t {
70     //! Unknown or uninitialized architecture.
71     kArchUnknown = 0,
72 
73     //! Mask used by 32-bit architectures (odd are 32-bit, even are 64-bit).
74     kArch32BitMask = 0x01,
75     //! Mask used by big-endian architectures.
76     kArchBigEndianMask = 0x80u,
77 
78     //! 32-bit X86 architecture.
79     kArchX86 = 1,
80     //! 64-bit X86 architecture also known as X86_64 and AMD64.
81     kArchX64 = 2,
82 
83     //! 32-bit RISC-V architecture.
84     kArchRISCV32 = 3,
85     //! 64-bit RISC-V architecture.
86     kArchRISCV64 = 4,
87 
88     //! 32-bit ARM architecture (little endian).
89     kArchARM = 5,
90     //! 32-bit ARM architecture (big endian).
91     kArchARM_BE = kArchARM | kArchBigEndianMask,
92     //! 64-bit ARM architecture in (little endian).
93     kArchAArch64 = 6,
94     //! 64-bit ARM architecture in (big endian).
95     kArchAArch64_BE = kArchAArch64 | kArchBigEndianMask,
96     //! 32-bit ARM in Thumb mode (little endian).
97     kArchThumb = 7,
98     //! 32-bit ARM in Thumb mode (big endian).
99     kArchThumb_BE = kArchThumb | kArchBigEndianMask,
100 
101     // 8 is not used, even numbers are 64-bit architectures.
102 
103     //! 32-bit MIPS architecture in (little endian).
104     kArchMIPS32_LE = 9,
105     //! 32-bit MIPS architecture in (big endian).
106     kArchMIPS32_BE = kArchMIPS32_LE | kArchBigEndianMask,
107     //! 64-bit MIPS architecture in (little endian).
108     kArchMIPS64_LE = 10,
109     //! 64-bit MIPS architecture in (big endian).
110     kArchMIPS64_BE = kArchMIPS64_LE | kArchBigEndianMask,
111 
112     //! Count of architectures.
113     kArchCount = 11
114   };
115 
116   //! Sub-architecture.
117   enum SubArch : uint32_t {
118     //! Unknown or uninitialized architecture sub-type.
119     kSubArchUnknown = 0,
120 
121     //! Count of sub-architectures.
122     kSubArchCount
123   };
124 
125   //! Vendor.
126   //!
127   //! \note AsmJit doesn't use vendor information at the moment. It's provided
128   //! for future use, if required.
129   enum Vendor : uint32_t {
130     //! Unknown or uninitialized vendor.
131     kVendorUnknown = 0,
132 
133     //! Count of vendor identifiers.
134     kVendorCount
135   };
136 
137   //! Platform / OS.
138   enum Platform : uint32_t {
139     //! Unknown or uninitialized platform.
140     kPlatformUnknown = 0,
141 
142     //! Windows OS.
143     kPlatformWindows,
144 
145     //! Other platform, most likely POSIX based.
146     kPlatformOther,
147 
148     //! Linux OS.
149     kPlatformLinux,
150     //! GNU/Hurd OS.
151     kPlatformHurd,
152 
153     //! FreeBSD OS.
154     kPlatformFreeBSD,
155     //! OpenBSD OS.
156     kPlatformOpenBSD,
157     //! NetBSD OS.
158     kPlatformNetBSD,
159     //! DragonFly BSD OS.
160     kPlatformDragonFlyBSD,
161 
162     //! Haiku OS.
163     kPlatformHaiku,
164 
165     //! Apple OSX.
166     kPlatformOSX,
167     //! Apple iOS.
168     kPlatformIOS,
169     //! Apple TVOS.
170     kPlatformTVOS,
171     //! Apple WatchOS.
172     kPlatformWatchOS,
173 
174     //! Emscripten platform.
175     kPlatformEmscripten,
176 
177     //! Count of platform identifiers.
178     kPlatformCount
179   };
180 
181   //! ABI.
182   enum Abi : uint32_t {
183     //! Unknown or uninitialied environment.
184     kAbiUnknown = 0,
185     //! Microsoft ABI.
186     kAbiMSVC,
187     //! GNU ABI.
188     kAbiGNU,
189     //! Android Environment / ABI.
190     kAbiAndroid,
191     //! Cygwin ABI.
192     kAbiCygwin,
193 
194     //! Count of known ABI types.
195     kAbiCount
196   };
197 
198   //! Object format.
199   //!
200   //! \note AsmJit doesn't really use anything except \ref kFormatUnknown and
201   //! \ref kFormatJIT at the moment. Object file formats are provided for
202   //! future extensibility and a possibility to generate object files at some
203   //! point.
204   enum Format : uint32_t {
205     //! Unknown or uninitialized object format.
206     kFormatUnknown = 0,
207 
208     //! JIT code generation object, most likely \ref JitRuntime or a custom
209     //! \ref Target implementation.
210     kFormatJIT,
211 
212     //! Executable and linkable format (ELF).
213     kFormatELF,
214     //! Common object file format.
215     kFormatCOFF,
216     //! Extended COFF object format.
217     kFormatXCOFF,
218     //! Mach object file format.
219     kFormatMachO,
220 
221     //! Count of object format types.
222     kFormatCount
223   };
224 
225   //! \name Environment Detection
226   //! \{
227 
228 #ifdef _DOXYGEN
229   //! Architecture detected at compile-time (architecture of the host).
230   static constexpr Arch kArchHost = DETECTED_AT_COMPILE_TIME;
231   //! Sub-architecture detected at compile-time (sub-architecture of the host).
232   static constexpr SubArch kSubArchHost = DETECTED_AT_COMPILE_TIME;
233   //! Vendor detected at compile-time (vendor of the host).
234   static constexpr Vendor kVendorHost = DETECTED_AT_COMPILE_TIME;
235   //! Platform detected at compile-time (platform of the host).
236   static constexpr Platform kPlatformHost = DETECTED_AT_COMPILE_TIME;
237   //! ABI detected at compile-time (ABI of the host).
238   static constexpr Abi kAbiHost = DETECTED_AT_COMPILE_TIME;
239 #else
240   static constexpr Arch kArchHost =
241     ASMJIT_ARCH_X86 == 32 ? kArchX86 :
242     ASMJIT_ARCH_X86 == 64 ? kArchX64 :
243 
244     ASMJIT_ARCH_ARM == 32 && ASMJIT_ARCH_LE ? kArchARM :
245     ASMJIT_ARCH_ARM == 32 && ASMJIT_ARCH_BE ? kArchARM_BE :
246     ASMJIT_ARCH_ARM == 64 && ASMJIT_ARCH_LE ? kArchAArch64 :
247     ASMJIT_ARCH_ARM == 64 && ASMJIT_ARCH_BE ? kArchAArch64_BE :
248 
249     ASMJIT_ARCH_MIPS == 32 && ASMJIT_ARCH_LE ? kArchMIPS32_LE :
250     ASMJIT_ARCH_MIPS == 32 && ASMJIT_ARCH_BE ? kArchMIPS32_BE :
251     ASMJIT_ARCH_MIPS == 64 && ASMJIT_ARCH_LE ? kArchMIPS64_LE :
252     ASMJIT_ARCH_MIPS == 64 && ASMJIT_ARCH_BE ? kArchMIPS64_BE :
253 
254     kArchUnknown;
255 
256   static constexpr SubArch kSubArchHost =
257     kSubArchUnknown;
258 
259   static constexpr Vendor kVendorHost =
260     kVendorUnknown;
261 
262   static constexpr Platform kPlatformHost =
263 #if defined(__EMSCRIPTEN__)
264     kPlatformEmscripten
265 #elif defined(_WIN32)
266     kPlatformWindows
267 #elif defined(__linux__)
268     kPlatformLinux
269 #elif defined(__gnu_hurd__)
270     kPlatformHurd
271 #elif defined(__FreeBSD__)
272     kPlatformFreeBSD
273 #elif defined(__OpenBSD__)
274     kPlatformOpenBSD
275 #elif defined(__NetBSD__)
276     kPlatformNetBSD
277 #elif defined(__DragonFly__)
278     kPlatformDragonFlyBSD
279 #elif defined(__HAIKU__)
280     kPlatformHaiku
281 #elif defined(__APPLE__) && TARGET_OS_OSX
282     kPlatformOSX
283 #elif defined(__APPLE__) && TARGET_OS_TV
284     kPlatformTVOS
285 #elif defined(__APPLE__) && TARGET_OS_WATCH
286     kPlatformWatchOS
287 #elif defined(__APPLE__) && TARGET_OS_IPHONE
288     kPlatformIOS
289 #else
290     kPlatformOther
291 #endif
292     ;
293 
294   static constexpr Abi kAbiHost =
295 #if defined(_MSC_VER)
296     kAbiMSVC
297 #elif defined(__CYGWIN__)
298     kAbiCygwin
299 #elif defined(__MINGW32__) || defined(__GLIBC__)
300     kAbiGNU
301 #elif defined(__ANDROID__)
302     kAbiAndroid
303 #else
304     kAbiUnknown
305 #endif
306     ;
307 
308 #endif
309 
310   //! \}
311 
312   //! \name Construction / Destruction
313   //! \{
314 
Environment()315   inline Environment() noexcept :
316     _arch(uint8_t(kArchUnknown)),
317     _subArch(uint8_t(kSubArchUnknown)),
318     _vendor(uint8_t(kVendorUnknown)),
319     _platform(uint8_t(kPlatformUnknown)),
320     _abi(uint8_t(kAbiUnknown)),
321     _format(uint8_t(kFormatUnknown)),
322     _reserved(0) {}
323 
324   inline Environment(const Environment& other) noexcept = default;
325 
326   inline explicit Environment(uint32_t arch,
327                               uint32_t subArch = kSubArchUnknown,
328                               uint32_t vendor = kVendorUnknown,
329                               uint32_t platform = kPlatformUnknown,
330                               uint32_t abi = kAbiUnknown,
331                               uint32_t format = kFormatUnknown) noexcept {
332     init(arch, subArch, vendor, platform, abi, format);
333   }
334 
335   //! \}
336 
337   //! \name Overloaded Operators
338   //! \{
339 
340   inline Environment& operator=(const Environment& other) noexcept = default;
341 
342   inline bool operator==(const Environment& other) const noexcept { return  equals(other); }
343   inline bool operator!=(const Environment& other) const noexcept { return !equals(other); }
344 
345   //! \}
346 
347   //! \name Accessors
348   //! \{
349 
350   //! Tests whether the environment is not set up.
351   //!
352   //! Returns true if all members are zero, and thus unknown.
empty()353   inline bool empty() const noexcept {
354     // Unfortunately compilers won't optimize fields are checked one by one...
355     return _packed() == 0;
356   }
357 
358   //! Tests whether the environment is intialized, which means it must have
359   //! a valid architecture.
isInitialized()360   inline bool isInitialized() const noexcept {
361     return _arch != kArchUnknown;
362   }
363 
_packed()364   inline uint64_t _packed() const noexcept {
365     uint64_t x;
366     memcpy(&x, this, 8);
367     return x;
368   }
369 
370   //! Resets all members of the environment to zero / unknown.
reset()371   inline void reset() noexcept {
372     _arch = uint8_t(kArchUnknown);
373     _subArch = uint8_t(kSubArchUnknown);
374     _vendor = uint8_t(kVendorUnknown);
375     _platform = uint8_t(kPlatformUnknown);
376     _abi = uint8_t(kAbiUnknown);
377     _format = uint8_t(kFormatUnknown);
378     _reserved = 0;
379   }
380 
equals(const Environment & other)381   inline bool equals(const Environment& other) const noexcept {
382     return _packed() == other._packed();
383   }
384 
385   //! Returns the architecture, see \ref Arch.
arch()386   inline uint32_t arch() const noexcept { return _arch; }
387   //! Returns the sub-architecture, see \ref SubArch.
subArch()388   inline uint32_t subArch() const noexcept { return _subArch; }
389   //! Returns vendor, see \ref Vendor.
vendor()390   inline uint32_t vendor() const noexcept { return _vendor; }
391   //! Returns target's platform or operating system, see \ref Platform.
platform()392   inline uint32_t platform() const noexcept { return _platform; }
393   //! Returns target's ABI, see \ref Abi.
abi()394   inline uint32_t abi() const noexcept { return _abi; }
395   //! Returns target's object format, see \ref Format.
format()396   inline uint32_t format() const noexcept { return _format; }
397 
398   inline void init(uint32_t arch,
399                    uint32_t subArch = kSubArchUnknown,
400                    uint32_t vendor = kVendorUnknown,
401                    uint32_t platform = kPlatformUnknown,
402                    uint32_t abi = kAbiUnknown,
403                    uint32_t format = kFormatUnknown) noexcept {
404     _arch = uint8_t(arch);
405     _subArch = uint8_t(subArch);
406     _vendor = uint8_t(vendor);
407     _platform = uint8_t(platform);
408     _abi = uint8_t(abi);
409     _format = uint8_t(format);
410     _reserved = 0;
411   }
412 
isArchX86()413   inline bool isArchX86() const noexcept { return _arch == kArchX86; }
isArchX64()414   inline bool isArchX64() const noexcept { return _arch == kArchX64; }
isArchRISCV32()415   inline bool isArchRISCV32() const noexcept { return _arch == kArchRISCV32; }
isArchRISCV64()416   inline bool isArchRISCV64() const noexcept { return _arch == kArchRISCV64; }
isArchARM()417   inline bool isArchARM() const noexcept { return (_arch & ~kArchBigEndianMask) == kArchARM; }
isArchThumb()418   inline bool isArchThumb() const noexcept { return (_arch & ~kArchBigEndianMask) == kArchThumb; }
isArchAArch64()419   inline bool isArchAArch64() const noexcept { return (_arch & ~kArchBigEndianMask) == kArchAArch64; }
isArchMIPS32()420   inline bool isArchMIPS32() const noexcept { return (_arch & ~kArchBigEndianMask) == kArchMIPS32_LE; }
isArchMIPS64()421   inline bool isArchMIPS64() const noexcept { return (_arch & ~kArchBigEndianMask) == kArchMIPS64_LE; }
422 
423   //! Tests whether the architecture is 32-bit.
is32Bit()424   inline bool is32Bit() const noexcept { return is32Bit(_arch); }
425   //! Tests whether the architecture is 64-bit.
is64Bit()426   inline bool is64Bit() const noexcept { return is64Bit(_arch); }
427 
428   //! Tests whether the architecture is little endian.
isLittleEndian()429   inline bool isLittleEndian() const noexcept { return isLittleEndian(_arch); }
430   //! Tests whether the architecture is big endian.
isBigEndian()431   inline bool isBigEndian() const noexcept { return isBigEndian(_arch); }
432 
433   //! Tests whether this architecture is of X86 family.
isFamilyX86()434   inline bool isFamilyX86() const noexcept { return isFamilyX86(_arch); }
435   //! Tests whether this architecture family is RISC-V (both 32-bit and 64-bit).
isFamilyRISCV()436   inline bool isFamilyRISCV() const noexcept { return isFamilyRISCV(_arch); }
437   //! Tests whether this architecture family is ARM, Thumb, or AArch64.
isFamilyARM()438   inline bool isFamilyARM() const noexcept { return isFamilyARM(_arch); }
439   //! Tests whether this architecture family is MISP or MIPS64.
isFamilyMIPS()440   inline bool isFamilyMIPS() const noexcept { return isFamilyMIPS(_arch); }
441 
442   //! Tests whether the environment platform is Windows.
isPlatformWindows()443   inline bool isPlatformWindows() const noexcept { return _platform == kPlatformWindows; }
444 
445   //! Tests whether the environment platform is Linux.
isPlatformLinux()446   inline bool isPlatformLinux() const noexcept { return _platform == kPlatformLinux; }
447 
448   //! Tests whether the environment platform is Hurd.
isPlatformHurd()449   inline bool isPlatformHurd() const noexcept { return _platform == kPlatformHurd; }
450 
451   //! Tests whether the environment platform is Haiku.
isPlatformHaiku()452   inline bool isPlatformHaiku() const noexcept { return _platform == kPlatformHaiku; }
453 
454   //! Tests whether the environment platform is any BSD.
isPlatformBSD()455   inline bool isPlatformBSD() const noexcept {
456     return _platform == kPlatformFreeBSD ||
457            _platform == kPlatformOpenBSD ||
458            _platform == kPlatformNetBSD ||
459            _platform == kPlatformDragonFlyBSD;
460   }
461 
462   //! Tests whether the environment platform is any Apple platform (OSX, iOS, TVOS, WatchOS).
isPlatformApple()463   inline bool isPlatformApple() const noexcept {
464     return _platform == kPlatformOSX ||
465            _platform == kPlatformIOS ||
466            _platform == kPlatformTVOS ||
467            _platform == kPlatformWatchOS;
468   }
469 
470   //! Tests whether the ABI is MSVC.
isAbiMSVC()471   inline bool isAbiMSVC() const noexcept { return _abi == kAbiMSVC; }
472   //! Tests whether the ABI is GNU.
isAbiGNU()473   inline bool isAbiGNU() const noexcept { return _abi == kAbiGNU; }
474 
475   //! Returns a calculated stack alignment for this environment.
476   ASMJIT_API uint32_t stackAlignment() const noexcept;
477 
478   //! Returns a native register size of this architecture.
registerSize()479   uint32_t registerSize() const noexcept { return registerSizeFromArch(_arch); }
480 
481   //! Sets the architecture to `arch`.
setArch(uint32_t arch)482   inline void setArch(uint32_t arch) noexcept { _arch = uint8_t(arch); }
483   //! Sets the sub-architecture to `subArch`.
setSubArch(uint32_t subArch)484   inline void setSubArch(uint32_t subArch) noexcept { _subArch = uint8_t(subArch); }
485   //! Sets the vendor to `vendor`.
setVendor(uint32_t vendor)486   inline void setVendor(uint32_t vendor) noexcept { _vendor = uint8_t(vendor); }
487   //! Sets the platform to `platform`.
setPlatform(uint32_t platform)488   inline void setPlatform(uint32_t platform) noexcept { _platform = uint8_t(platform); }
489   //! Sets the ABI to `abi`.
setAbi(uint32_t abi)490   inline void setAbi(uint32_t abi) noexcept { _abi = uint8_t(abi); }
491   //! Sets the object format to `format`.
setFormat(uint32_t format)492   inline void setFormat(uint32_t format) noexcept { _format = uint8_t(format); }
493 
494   //! \}
495 
496   //! \name Static Utilities
497   //! \{
498 
isValidArch(uint32_t arch)499   static inline bool isValidArch(uint32_t arch) noexcept {
500     return (arch & ~kArchBigEndianMask) != 0 &&
501            (arch & ~kArchBigEndianMask) < kArchCount;
502   }
503 
504   //! Tests whether the given architecture `arch` is 32-bit.
is32Bit(uint32_t arch)505   static inline bool is32Bit(uint32_t arch) noexcept {
506     return (arch & kArch32BitMask) == kArch32BitMask;
507   }
508 
509   //! Tests whether the given architecture `arch` is 64-bit.
is64Bit(uint32_t arch)510   static inline bool is64Bit(uint32_t arch) noexcept {
511     return (arch & kArch32BitMask) == 0;
512   }
513 
514   //! Tests whether the given architecture `arch` is little endian.
isLittleEndian(uint32_t arch)515   static inline bool isLittleEndian(uint32_t arch) noexcept {
516     return (arch & kArchBigEndianMask) == 0;
517   }
518 
519   //! Tests whether the given architecture `arch` is big endian.
isBigEndian(uint32_t arch)520   static inline bool isBigEndian(uint32_t arch) noexcept {
521     return (arch & kArchBigEndianMask) == kArchBigEndianMask;
522   }
523 
524   //! Tests whether the given architecture is AArch64.
isArchAArch64(uint32_t arch)525   static inline bool isArchAArch64(uint32_t arch) noexcept {
526     arch &= ~kArchBigEndianMask;
527     return arch == kArchAArch64;
528   }
529 
530   //! Tests whether the given architecture family is X86 or X64.
isFamilyX86(uint32_t arch)531   static inline bool isFamilyX86(uint32_t arch) noexcept {
532     return arch == kArchX86 ||
533            arch == kArchX64;
534   }
535 
536   //! Tests whether the given architecture family is RISC-V (both 32-bit and 64-bit).
isFamilyRISCV(uint32_t arch)537   static inline bool isFamilyRISCV(uint32_t arch) noexcept {
538     return arch == kArchRISCV32 ||
539            arch == kArchRISCV64;
540   }
541 
542   //! Tests whether the given architecture family is ARM, Thumb, or AArch64.
isFamilyARM(uint32_t arch)543   static inline bool isFamilyARM(uint32_t arch) noexcept {
544     arch &= ~kArchBigEndianMask;
545     return arch == kArchARM ||
546            arch == kArchAArch64 ||
547            arch == kArchThumb;
548   }
549 
550   //! Tests whether the given architecture family is MISP or MIPS64.
isFamilyMIPS(uint32_t arch)551   static inline bool isFamilyMIPS(uint32_t arch) noexcept {
552     arch &= ~kArchBigEndianMask;
553     return arch == kArchMIPS32_LE ||
554            arch == kArchMIPS64_LE;
555   }
556 
557   //! Returns a native general purpose register size from the given architecture.
registerSizeFromArch(uint32_t arch)558   static uint32_t registerSizeFromArch(uint32_t arch) noexcept {
559     return is32Bit(arch) ? 4u : 8u;
560   }
561 
562   //! \}
563 };
564 
565 //! Returns the host environment constructed from preprocessor macros defined
566 //! by the compiler.
567 //!
568 //! The returned environment should precisely match the target host architecture,
569 //! sub-architecture, platform, and ABI.
hostEnvironment()570 static ASMJIT_INLINE Environment hostEnvironment() noexcept {
571   return Environment(Environment::kArchHost,
572                      Environment::kSubArchHost,
573                      Environment::kVendorHost,
574                      Environment::kPlatformHost,
575                      Environment::kAbiHost,
576                      Environment::kFormatUnknown);
577 }
578 
579 static_assert(sizeof(Environment) == 8,
580               "Environment must occupy exactly 8 bytes.");
581 
582 //! \}
583 
584 #ifndef ASMJIT_NO_DEPRECATED
585 class ASMJIT_DEPRECATED_STRUCT("Use Environment instead") ArchInfo : public Environment {
586 public:
ArchInfo()587   inline ArchInfo() noexcept : Environment() {}
588 
ArchInfo(const Environment & other)589   inline ArchInfo(const Environment& other) noexcept : Environment(other) {}
590   inline explicit ArchInfo(uint32_t arch, uint32_t subArch = kSubArchUnknown) noexcept
Environment(arch,subArch)591     : Environment(arch, subArch) {}
592 
593   enum Id : uint32_t {
594     kIdNone = Environment::kArchUnknown,
595     kIdX86 = Environment::kArchX86,
596     kIdX64 = Environment::kArchX64,
597     kIdA32 = Environment::kArchARM,
598     kIdA64 = Environment::kArchAArch64,
599     kIdHost = Environment::kArchHost
600   };
601 
602   enum SubType : uint32_t {
603     kSubIdNone = Environment::kSubArchUnknown
604   };
605 
host()606   static inline ArchInfo host() noexcept { return ArchInfo(hostEnvironment()); }
607 };
608 #endif // !ASMJIT_NO_DEPRECATED
609 
610 ASMJIT_END_NAMESPACE
611 
612 #endif // ASMJIT_CORE_ENVIRONMENT_H_INCLUDED
613