odin-blend2d

Odin bindings to Blend2D
Log | Files | Refs | README | LICENSE

environment.h (19991B)


      1 // This file is part of AsmJit project <https://asmjit.com>
      2 //
      3 // See <asmjit/core.h> or LICENSE.md for license and copyright information
      4 // SPDX-License-Identifier: Zlib
      5 
      6 #ifndef ASMJIT_CORE_ENVIRONMENT_H_INCLUDED
      7 #define ASMJIT_CORE_ENVIRONMENT_H_INCLUDED
      8 
      9 #include "../core/archtraits.h"
     10 
     11 #if defined(__APPLE__)
     12   #include <TargetConditionals.h>
     13 #endif
     14 
     15 ASMJIT_BEGIN_NAMESPACE
     16 
     17 //! \addtogroup asmjit_core
     18 //! \{
     19 
     20 //! Vendor.
     21 //!
     22 //! \note AsmJit doesn't use vendor information at the moment. It's provided for future use, if required.
     23 enum class Vendor : uint8_t {
     24   //! Unknown or uninitialized platform vendor.
     25   kUnknown = 0,
     26 
     27   //! Maximum value of `Vendor`.
     28   kMaxValue = kUnknown,
     29 
     30   //! Platform vendor detected at compile-time.
     31   kHost =
     32 #if defined(_DOXYGEN)
     33     DETECTED_AT_COMPILE_TIME
     34 #else
     35     kUnknown
     36 #endif
     37 };
     38 
     39 //! Platform - runtime environment or operating system.
     40 enum class Platform : uint8_t {
     41   //! Unknown or uninitialized platform.
     42   kUnknown = 0,
     43 
     44   //! Windows OS.
     45   kWindows,
     46 
     47   //! Other platform that is not Windows, most likely POSIX based.
     48   kOther,
     49 
     50   //! Linux OS.
     51   kLinux,
     52   //! GNU/Hurd OS.
     53   kHurd,
     54 
     55   //! FreeBSD OS.
     56   kFreeBSD,
     57   //! OpenBSD OS.
     58   kOpenBSD,
     59   //! NetBSD OS.
     60   kNetBSD,
     61   //! DragonFly BSD OS.
     62   kDragonFlyBSD,
     63 
     64   //! Haiku OS.
     65   kHaiku,
     66 
     67   //! Apple OSX.
     68   kOSX,
     69   //! Apple iOS.
     70   kIOS,
     71   //! Apple TVOS.
     72   kTVOS,
     73   //! Apple WatchOS.
     74   kWatchOS,
     75 
     76   //! Emscripten platform.
     77   kEmscripten,
     78 
     79   //! Maximum value of `Platform`.
     80   kMaxValue = kEmscripten,
     81 
     82   //! Platform detected at compile-time (platform of the host).
     83   kHost =
     84 #if defined(_DOXYGEN)
     85     DETECTED_AT_COMPILE_TIME
     86 #elif defined(__EMSCRIPTEN__)
     87     kEmscripten
     88 #elif defined(_WIN32)
     89     kWindows
     90 #elif defined(__linux__)
     91     kLinux
     92 #elif defined(__gnu_hurd__)
     93     kHurd
     94 #elif defined(__FreeBSD__)
     95     kFreeBSD
     96 #elif defined(__OpenBSD__)
     97     kOpenBSD
     98 #elif defined(__NetBSD__)
     99     kNetBSD
    100 #elif defined(__DragonFly__)
    101     kDragonFlyBSD
    102 #elif defined(__HAIKU__)
    103     kHaiku
    104 #elif defined(__APPLE__) && TARGET_OS_OSX
    105     kOSX
    106 #elif defined(__APPLE__) && TARGET_OS_TV
    107     kTVOS
    108 #elif defined(__APPLE__) && TARGET_OS_WATCH
    109     kWatchOS
    110 #elif defined(__APPLE__) && TARGET_OS_IPHONE
    111     kIOS
    112 #else
    113     kOther
    114 #endif
    115 };
    116 
    117 //! Platform ABI (application binary interface).
    118 enum class PlatformABI : uint8_t {
    119   //! Unknown or uninitialized environment.
    120   kUnknown = 0,
    121   //! Microsoft ABI.
    122   kMSVC,
    123   //! GNU ABI.
    124   kGNU,
    125   //! Android Environment / ABI.
    126   kAndroid,
    127   //! Cygwin ABI.
    128   kCygwin,
    129   //! Darwin ABI.
    130   kDarwin,
    131 
    132   //! Maximum value of `PlatformABI`.
    133   kMaxValue,
    134 
    135   //! Host ABI detected at compile-time.
    136   kHost =
    137 #if defined(_DOXYGEN)
    138     DETECTED_AT_COMPILE_TIME
    139 #elif defined(_MSC_VER)
    140     kMSVC
    141 #elif defined(__CYGWIN__)
    142     kCygwin
    143 #elif defined(__MINGW32__) || defined(__GLIBC__)
    144     kGNU
    145 #elif defined(__ANDROID__)
    146     kAndroid
    147 #elif defined(__APPLE__)
    148     kDarwin
    149 #else
    150     kUnknown
    151 #endif
    152 };
    153 
    154 //! Floating point ABI (ARM).
    155 enum class FloatABI : uint8_t {
    156   kHardFloat = 0,
    157   kSoftFloat,
    158 
    159   kHost =
    160 #if ASMJIT_ARCH_ARM == 32 && defined(__SOFTFP__)
    161   kSoftFloat
    162 #else
    163   kHardFloat
    164 #endif
    165 };
    166 
    167 //! Object format.
    168 //!
    169 //! \note AsmJit doesn't really use anything except \ref ObjectFormat::kUnknown and \ref ObjectFormat::kJIT at
    170 //! the moment. Object file formats are provided for future extensibility and a possibility to generate object
    171 //! files at some point.
    172 enum class ObjectFormat : uint8_t {
    173   //! Unknown or uninitialized object format.
    174   kUnknown = 0,
    175 
    176   //! JIT code generation object, most likely \ref JitRuntime or a custom
    177   //! \ref Target implementation.
    178   kJIT,
    179 
    180   //! Executable and linkable format (ELF).
    181   kELF,
    182   //! Common object file format.
    183   kCOFF,
    184   //! Extended COFF object format.
    185   kXCOFF,
    186   //! Mach object file format.
    187   kMachO,
    188 
    189   //! Maximum value of `ObjectFormat`.
    190   kMaxValue
    191 };
    192 
    193 //! Represents an environment, which is usually related to a \ref Target.
    194 //!
    195 //! Environment has usually an 'arch-subarch-vendor-os-abi' format, which is sometimes called "Triple" (historically
    196 //! it used to be 3 only parts) or "Tuple", which is a convention used by Debian Linux.
    197 //!
    198 //! AsmJit doesn't support all possible combinations or architectures and ABIs, however, it models the environment
    199 //! similarly to other compilers for future extensibility.
    200 class Environment {
    201 public:
    202   //! \name Members
    203   //! \{
    204 
    205   //! Architecture.
    206   Arch _arch = Arch::kUnknown;
    207   //! Sub-architecture type.
    208   SubArch _sub_arch = SubArch::kUnknown;
    209   //! Vendor type.
    210   Vendor _vendor = Vendor::kUnknown;
    211   //! Platform.
    212   Platform _platform = Platform::kUnknown;
    213   //! Platform ABI.
    214   PlatformABI _platform_abi = PlatformABI::kUnknown;
    215   //! Object format.
    216   ObjectFormat _object_format = ObjectFormat::kUnknown;
    217   //! Floating point ABI.
    218   FloatABI _float_abi = FloatABI::kHardFloat;
    219   //! Reserved for future use, must be zero.
    220   uint8_t _reserved = 0;
    221 
    222   //! \}
    223 
    224   //! \name Construction & Destruction
    225   //! \{
    226 
    227   //! Creates a default initialized environment (all values either unknown or set to safe defaults).
    228   ASMJIT_INLINE_CONSTEXPR Environment() noexcept = default;
    229   //! Creates a copy of `other` instance.
    230   ASMJIT_INLINE_CONSTEXPR Environment(const Environment& other) noexcept = default;
    231 
    232   //! Creates \ref Environment initialized to `arch`, `sub_arch`, `vendor`, `platform`, `platform_abi`, `object_format`,
    233   //! and `float_abi`.
    234   ASMJIT_INLINE_CONSTEXPR explicit Environment(
    235     Arch arch,
    236     SubArch sub_arch = SubArch::kUnknown,
    237     Vendor vendor = Vendor::kUnknown,
    238     Platform platform = Platform::kUnknown,
    239     PlatformABI platform_abi = PlatformABI::kUnknown,
    240     ObjectFormat object_format = ObjectFormat::kUnknown,
    241     FloatABI float_abi = FloatABI::kHardFloat) noexcept
    242     : _arch(arch),
    243       _sub_arch(sub_arch),
    244       _vendor(vendor),
    245       _platform(platform),
    246       _platform_abi(platform_abi),
    247       _object_format(object_format),
    248       _float_abi(float_abi) {}
    249 
    250   //! Returns the host environment constructed from preprocessor macros defined by the compiler.
    251   //!
    252   //! The returned environment should precisely match the target host architecture, sub-architecture, platform,
    253   //! and ABI.
    254   static ASMJIT_INLINE_CONSTEXPR Environment host() noexcept {
    255     return Environment(Arch::kHost, SubArch::kHost, Vendor::kHost, Platform::kHost, PlatformABI::kHost, ObjectFormat::kUnknown, FloatABI::kHost);
    256   }
    257 
    258   //! \}
    259 
    260   //! \name Overloaded Operators
    261   //! \{
    262 
    263   ASMJIT_INLINE_NODEBUG Environment& operator=(const Environment& other) noexcept = default;
    264 
    265   [[nodiscard]]
    266   ASMJIT_INLINE_NODEBUG bool operator==(const Environment& other) const noexcept { return equals(other); }
    267 
    268   [[nodiscard]]
    269   ASMJIT_INLINE_NODEBUG bool operator!=(const Environment& other) const noexcept { return !equals(other); }
    270 
    271   //! \}
    272 
    273   //! \name Accessors
    274   //! \{
    275 
    276   //! Tests whether the environment is not set up.
    277   //!
    278   //! Returns true if all members are zero, and thus unknown.
    279   [[nodiscard]]
    280   ASMJIT_INLINE_NODEBUG bool is_empty() const noexcept {
    281     // Unfortunately compilers won't optimize fields are checked one by one...
    282     return _packed() == 0;
    283   }
    284 
    285   //! Tests whether the environment is initialized, which means it must have
    286   //! a valid architecture.
    287   [[nodiscard]]
    288   ASMJIT_INLINE_NODEBUG bool is_initialized() const noexcept {
    289     return _arch != Arch::kUnknown;
    290   }
    291 
    292   [[nodiscard]]
    293   ASMJIT_INLINE_NODEBUG uint64_t _packed() const noexcept {
    294     uint64_t x;
    295     memcpy(&x, this, 8);
    296     return x;
    297   }
    298 
    299   //! Resets all members of the environment to zero / unknown.
    300   ASMJIT_INLINE_NODEBUG void reset() noexcept { *this = Environment{}; }
    301 
    302   //! Tests whether this environment is equal to `other`.
    303   [[nodiscard]]
    304   ASMJIT_INLINE_NODEBUG bool equals(const Environment& other) const noexcept { return _packed() == other._packed(); }
    305 
    306   //! Returns the architecture.
    307   [[nodiscard]]
    308   ASMJIT_INLINE_NODEBUG Arch arch() const noexcept { return _arch; }
    309 
    310   //! Returns the sub-architecture.
    311   [[nodiscard]]
    312   ASMJIT_INLINE_NODEBUG SubArch sub_arch() const noexcept { return _sub_arch; }
    313 
    314   //! Returns vendor.
    315   [[nodiscard]]
    316   ASMJIT_INLINE_NODEBUG Vendor vendor() const noexcept { return _vendor; }
    317 
    318   //! Returns target's platform or operating system.
    319   [[nodiscard]]
    320   ASMJIT_INLINE_NODEBUG Platform platform() const noexcept { return _platform; }
    321 
    322   //! Returns target's ABI.
    323   [[nodiscard]]
    324   ASMJIT_INLINE_NODEBUG PlatformABI platform_abi() const noexcept { return _platform_abi; }
    325 
    326   //! Returns target's object format.
    327   [[nodiscard]]
    328   ASMJIT_INLINE_NODEBUG ObjectFormat object_format() const noexcept { return _object_format; }
    329 
    330   //! Returns floating point ABI.
    331   [[nodiscard]]
    332   ASMJIT_INLINE_NODEBUG FloatABI float_abi() const noexcept { return _float_abi; }
    333 
    334   //! Initializes \ref Environment to `arch`, `sub_arch`, `vendor`, `platform`, `platform_abi`, `object_format`,
    335   //! and `float_abi`.
    336   inline void init(
    337     Arch arch,
    338     SubArch sub_arch = SubArch::kUnknown,
    339     Vendor vendor = Vendor::kUnknown,
    340     Platform platform = Platform::kUnknown,
    341     PlatformABI platform_abi = PlatformABI::kUnknown,
    342     ObjectFormat object_format = ObjectFormat::kUnknown,
    343     FloatABI float_abi = FloatABI::kHardFloat) noexcept {
    344 
    345     _arch = arch;
    346     _sub_arch = sub_arch;
    347     _vendor = vendor;
    348     _platform = platform;
    349     _platform_abi = platform_abi;
    350     _object_format = object_format;
    351     _float_abi = float_abi;
    352     _reserved = 0;
    353   }
    354 
    355   //! Tests whether this environment describes a 32-bit X86.
    356   [[nodiscard]]
    357   ASMJIT_INLINE_NODEBUG bool is_arch_x86() const noexcept { return _arch == Arch::kX86; }
    358 
    359   //! Tests whether this environment describes a 64-bit X86.
    360   [[nodiscard]]
    361   ASMJIT_INLINE_NODEBUG bool is_arch_x64() const noexcept { return _arch == Arch::kX64; }
    362 
    363   //! Tests whether this environment describes a 32-bit ARM.
    364   [[nodiscard]]
    365   ASMJIT_INLINE_NODEBUG bool is_arch_arm() const noexcept { return is_arch_arm(_arch); }
    366 
    367   //! Tests whether this environment describes a 32-bit ARM in THUMB mode.
    368   [[nodiscard]]
    369   ASMJIT_INLINE_NODEBUG bool is_arch_thumb() const noexcept { return is_arch_thumb(_arch); }
    370 
    371   //! Tests whether this environment describes a 64-bit X86.
    372   [[nodiscard]]
    373   ASMJIT_INLINE_NODEBUG bool is_arch_aarch64() const noexcept { return is_arch_aarch64(_arch); }
    374 
    375   //! Tests whether this environment describes a 32-bit MIPS.
    376   [[nodiscard]]
    377   ASMJIT_INLINE_NODEBUG bool is_arch_mips32() const noexcept { return is_arch_mips32(_arch); }
    378 
    379   //! Tests whether this environment describes a 64-bit MIPS.
    380   [[nodiscard]]
    381   ASMJIT_INLINE_NODEBUG bool is_arch_mips64() const noexcept { return is_arch_mips64(_arch); }
    382 
    383   //! Tests whether this environment describes a 32-bit RISC-V.
    384   [[nodiscard]]
    385   ASMJIT_INLINE_NODEBUG bool is_arch_riscv32() const noexcept { return _arch == Arch::kRISCV32; }
    386 
    387   //! Tests whether this environment describes a 64-bit RISC-V.
    388   [[nodiscard]]
    389   ASMJIT_INLINE_NODEBUG bool is_arch_riscv64() const noexcept { return _arch == Arch::kRISCV64; }
    390 
    391   //! Tests whether the architecture is 32-bit.
    392   [[nodiscard]]
    393   ASMJIT_INLINE_NODEBUG bool is_32bit() const noexcept { return is_32bit(_arch); }
    394 
    395   //! Tests whether the architecture is 64-bit.
    396   [[nodiscard]]
    397   ASMJIT_INLINE_NODEBUG bool is_64bit() const noexcept { return is_64bit(_arch); }
    398 
    399   //! Tests whether the architecture is little endian.
    400   [[nodiscard]]
    401   ASMJIT_INLINE_NODEBUG bool is_little_endian() const noexcept { return is_little_endian(_arch); }
    402 
    403   //! Tests whether the architecture is big endian.
    404   [[nodiscard]]
    405   ASMJIT_INLINE_NODEBUG bool is_big_endian() const noexcept { return is_big_endian(_arch); }
    406 
    407   //! Tests whether this architecture is of X86 family.
    408   [[nodiscard]]
    409   ASMJIT_INLINE_NODEBUG bool is_family_x86() const noexcept { return is_family_x86(_arch); }
    410 
    411   //! Tests whether this architecture family is ARM, THUMB, or AArch64.
    412   [[nodiscard]]
    413   ASMJIT_INLINE_NODEBUG bool is_family_arm() const noexcept { return is_family_arm(_arch); }
    414 
    415   //! Tests whether this architecture family is AArch32 (ARM or THUMB).
    416   [[nodiscard]]
    417   ASMJIT_INLINE_NODEBUG bool is_family_aarch32() const noexcept { return is_family_aarch32(_arch); }
    418 
    419   //! Tests whether this architecture family is AArch64.
    420   [[nodiscard]]
    421   ASMJIT_INLINE_NODEBUG bool is_family_aarch64() const noexcept { return is_family_aarch64(_arch); }
    422 
    423   //! Tests whether this architecture family is MISP or MIPS64.
    424   [[nodiscard]]
    425   ASMJIT_INLINE_NODEBUG bool is_family_mips() const noexcept { return is_family_mips(_arch); }
    426 
    427   //! Tests whether this architecture family is RISC-V (both 32-bit and 64-bit).
    428   [[nodiscard]]
    429   ASMJIT_INLINE_NODEBUG bool is_family_riscv() const noexcept { return is_family_riscv(_arch); }
    430 
    431   //! Tests whether the environment platform is Windows.
    432   [[nodiscard]]
    433   ASMJIT_INLINE_NODEBUG bool is_platform_windows() const noexcept { return _platform == Platform::kWindows; }
    434 
    435   //! Tests whether the environment platform is Linux.
    436   [[nodiscard]]
    437   ASMJIT_INLINE_NODEBUG bool is_platform_linux() const noexcept { return _platform == Platform::kLinux; }
    438 
    439   //! Tests whether the environment platform is Hurd.
    440   [[nodiscard]]
    441   ASMJIT_INLINE_NODEBUG bool is_platform_hurd() const noexcept { return _platform == Platform::kHurd; }
    442 
    443   //! Tests whether the environment platform is Haiku.
    444   [[nodiscard]]
    445   ASMJIT_INLINE_NODEBUG bool is_platform_haiku() const noexcept { return _platform == Platform::kHaiku; }
    446 
    447   //! Tests whether the environment platform is any BSD.
    448   [[nodiscard]]
    449   ASMJIT_INLINE_NODEBUG bool is_platform_bsd() const noexcept {
    450     return _platform == Platform::kFreeBSD ||
    451            _platform == Platform::kOpenBSD ||
    452            _platform == Platform::kNetBSD ||
    453            _platform == Platform::kDragonFlyBSD;
    454   }
    455 
    456   //! Tests whether the environment platform is any Apple platform (OSX, iOS, TVOS, WatchOS).
    457   [[nodiscard]]
    458   ASMJIT_INLINE_NODEBUG bool is_platform_apple() const noexcept {
    459     return _platform == Platform::kOSX ||
    460            _platform == Platform::kIOS ||
    461            _platform == Platform::kTVOS ||
    462            _platform == Platform::kWatchOS;
    463   }
    464 
    465   //! Tests whether the ABI is MSVC.
    466   [[nodiscard]]
    467   ASMJIT_INLINE_NODEBUG bool is_msvc_abi() const noexcept { return _platform_abi == PlatformABI::kMSVC; }
    468 
    469   //! Tests whether the ABI is GNU.
    470   [[nodiscard]]
    471   ASMJIT_INLINE_NODEBUG bool is_gnu_abi() const noexcept { return _platform_abi == PlatformABI::kGNU; }
    472 
    473   //! Tests whether the ABI is GNU.
    474   [[nodiscard]]
    475   ASMJIT_INLINE_NODEBUG bool is_darwin_abi() const noexcept { return _platform_abi == PlatformABI::kDarwin; }
    476 
    477   //! Returns a calculated stack alignment for this environment.
    478   [[nodiscard]]
    479   ASMJIT_API uint32_t stack_alignment() const noexcept;
    480 
    481   //! Returns a native register size of this architecture.
    482   [[nodiscard]]
    483   ASMJIT_INLINE_NODEBUG uint32_t register_size() const noexcept { return reg_size_of_arch(_arch); }
    484 
    485   //! Sets the architecture to `arch`.
    486   ASMJIT_INLINE_NODEBUG void set_arch(Arch arch) noexcept { _arch = arch; }
    487   //! Sets the sub-architecture to `sub_arch`.
    488   ASMJIT_INLINE_NODEBUG void set_sub_arch(SubArch sub_arch) noexcept { _sub_arch = sub_arch; }
    489   //! Sets the vendor to `vendor`.
    490   ASMJIT_INLINE_NODEBUG void set_vendor(Vendor vendor) noexcept { _vendor = vendor; }
    491   //! Sets the platform to `platform`.
    492   ASMJIT_INLINE_NODEBUG void set_platform(Platform platform) noexcept { _platform = platform; }
    493   //! Sets the ABI to `platform_abi`.
    494   ASMJIT_INLINE_NODEBUG void set_platform_abi(PlatformABI platform_abi) noexcept { _platform_abi = platform_abi; }
    495   //! Sets the object format to `object_format`.
    496   ASMJIT_INLINE_NODEBUG void set_object_format(ObjectFormat object_format) noexcept { _object_format = object_format; }
    497 
    498   //! Sets floating point ABI to `float_abi`.
    499   ASMJIT_INLINE_NODEBUG void set_float_abi(FloatABI float_abi) noexcept { _float_abi = float_abi; }
    500 
    501   //! \}
    502 
    503   //! \name Static Utilities
    504   //! \{
    505 
    506   [[nodiscard]]
    507   static ASMJIT_INLINE_NODEBUG bool is_defined_arch(Arch arch) noexcept {
    508     return uint32_t(arch) <= uint32_t(Arch::kMaxValue);
    509   }
    510 
    511   [[nodiscard]]
    512   static ASMJIT_INLINE_NODEBUG bool is_valid_arch(Arch arch) noexcept {
    513     return arch != Arch::kUnknown && uint32_t(arch) <= uint32_t(Arch::kMaxValue);
    514   }
    515 
    516   //! Tests whether the given architecture `arch` is 32-bit.
    517   [[nodiscard]]
    518   static ASMJIT_INLINE_NODEBUG bool is_32bit(Arch arch) noexcept {
    519     return (uint32_t(arch) & uint32_t(Arch::k32BitMask)) == uint32_t(Arch::k32BitMask);
    520   }
    521 
    522   //! Tests whether the given architecture `arch` is 64-bit.
    523   [[nodiscard]]
    524   static ASMJIT_INLINE_NODEBUG bool is_64bit(Arch arch) noexcept {
    525     return (uint32_t(arch) & uint32_t(Arch::k32BitMask)) == 0;
    526   }
    527 
    528   //! Tests whether the given architecture `arch` is little endian.
    529   [[nodiscard]]
    530   static ASMJIT_INLINE_NODEBUG bool is_little_endian(Arch arch) noexcept {
    531     return uint32_t(arch) < uint32_t(Arch::kBigEndian);
    532   }
    533 
    534   //! Tests whether the given architecture `arch` is big endian.
    535   [[nodiscard]]
    536   static ASMJIT_INLINE_NODEBUG bool is_big_endian(Arch arch) noexcept {
    537     return uint32_t(arch) >= uint32_t(Arch::kBigEndian);
    538   }
    539 
    540   //! Tests whether the given architecture is Thumb or Thumb_BE.
    541   [[nodiscard]]
    542   static ASMJIT_INLINE_NODEBUG bool is_arch_thumb(Arch arch) noexcept {
    543     return arch == Arch::kThumb || arch == Arch::kThumb_BE;
    544   }
    545 
    546   //! Tests whether the given architecture is ARM or ARM_BE.
    547   [[nodiscard]]
    548   static ASMJIT_INLINE_NODEBUG bool is_arch_arm(Arch arch) noexcept {
    549     return arch == Arch::kARM || arch == Arch::kARM_BE;
    550   }
    551 
    552   //! Tests whether the given architecture is AArch64 or AArch64_BE.
    553   [[nodiscard]]
    554   static ASMJIT_INLINE_NODEBUG bool is_arch_aarch64(Arch arch) noexcept {
    555     return arch == Arch::kAArch64 || arch == Arch::kAArch64_BE;
    556   }
    557 
    558   //! Tests whether the given architecture is MIPS32_LE or MIPS32_BE.
    559   [[nodiscard]]
    560   static ASMJIT_INLINE_NODEBUG bool is_arch_mips32(Arch arch) noexcept {
    561     return arch == Arch::kMIPS32_LE || arch == Arch::kMIPS32_BE;
    562   }
    563 
    564   //! Tests whether the given architecture is MIPS64_LE or MIPS64_BE.
    565   [[nodiscard]]
    566   static ASMJIT_INLINE_NODEBUG bool is_arch_mips64(Arch arch) noexcept {
    567     return arch == Arch::kMIPS64_LE || arch == Arch::kMIPS64_BE;
    568   }
    569 
    570   //! Tests whether the given architecture family is X86 or X64.
    571   [[nodiscard]]
    572   static ASMJIT_INLINE_NODEBUG bool is_family_x86(Arch arch) noexcept {
    573     return arch == Arch::kX86 || arch == Arch::kX64;
    574   }
    575 
    576   //! Tests whether the given architecture family is AArch32 (ARM or THUMB).
    577   [[nodiscard]]
    578   static ASMJIT_INLINE_NODEBUG bool is_family_aarch32(Arch arch) noexcept {
    579     return is_arch_arm(arch) || is_arch_thumb(arch);
    580   }
    581 
    582   //! Tests whether the given architecture family is AArch64.
    583   [[nodiscard]]
    584   static ASMJIT_INLINE_NODEBUG bool is_family_aarch64(Arch arch) noexcept {
    585     return is_arch_aarch64(arch);
    586   }
    587 
    588   //! Tests whether the given architecture family is ARM, THUMB, or AArch64.
    589   [[nodiscard]]
    590   static ASMJIT_INLINE_NODEBUG bool is_family_arm(Arch arch) noexcept {
    591     return is_family_aarch32(arch) || is_family_aarch64(arch);
    592   }
    593 
    594   //! Tests whether the given architecture family is MIPS or MIPS64.
    595   [[nodiscard]]
    596   static ASMJIT_INLINE_NODEBUG bool is_family_mips(Arch arch) noexcept {
    597     return is_arch_mips32(arch) || is_arch_mips64(arch);
    598   }
    599 
    600   //! Tests whether the given architecture family is RISC-V (both 32-bit and 64-bit).
    601   [[nodiscard]]
    602   static ASMJIT_INLINE_NODEBUG bool is_family_riscv(Arch arch) noexcept {
    603     return arch == Arch::kRISCV32 || arch == Arch::kRISCV64;
    604   }
    605 
    606   //! Returns a native general purpose register size from the given architecture.
    607   [[nodiscard]]
    608   static ASMJIT_INLINE_NODEBUG uint32_t reg_size_of_arch(Arch arch) noexcept {
    609     return is_32bit(arch) ? 4u : 8u;
    610   }
    611 
    612   //! \}
    613 };
    614 
    615 static_assert(sizeof(Environment) == 8,
    616               "Environment must occupy exactly 8 bytes.");
    617 
    618 //! \}
    619 
    620 ASMJIT_END_NAMESPACE
    621 
    622 #endif // ASMJIT_CORE_ENVIRONMENT_H_INCLUDED