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