LCOV - code coverage report
Current view: top level - asmjit - environment.h (source / functions) Hit Total Coverage
Test: plumed test coverage (other modules) Lines: 28 38 73.7 %
Date: 2026-11-05 10:19:06 Functions: 0 2 0.0 %

          Line data    Source code
       1             : #ifdef __PLUMED_HAS_ASMJIT
       2             : // This file is part of AsmJit project <https://asmjit.com>
       3             : //
       4             : // See asmjit.h or LICENSE.md for license and copyright information
       5             : // SPDX-License-Identifier: Zlib
       6             : 
       7             : #ifndef ASMJIT_CORE_ENVIRONMENT_H_INCLUDED
       8             : #define ASMJIT_CORE_ENVIRONMENT_H_INCLUDED
       9             : 
      10             : #include "archtraits.h"
      11             : 
      12             : #if defined(__APPLE__)
      13             :   #include <TargetConditionals.h>
      14             : #endif
      15             : 
      16             : ASMJIT_BEGIN_NAMESPACE
      17             : 
      18             : //! \addtogroup asmjit_core
      19             : //! \{
      20             : 
      21             : //! Vendor.
      22             : //!
      23             : //! \note AsmJit doesn't use vendor information at the moment. It's provided for future use, if required.
      24             : enum class Vendor : uint8_t {
      25             :   //! Unknown or uninitialized platform vendor.
      26             :   kUnknown = 0,
      27             : 
      28             :   //! Maximum value of `PlatformVendor`.
      29             :   kMaxValue = kUnknown,
      30             : 
      31             :   //! Platform vendor detected at compile-time.
      32             :   kHost =
      33             : #if defined(_DOXYGEN)
      34             :     DETECTED_AT_COMPILE_TIME
      35             : #else
      36             :     kUnknown
      37             : #endif
      38             : };
      39             : 
      40             : //! Platform - runtime environment or operating system.
      41             : enum class Platform : uint8_t {
      42             :   //! Unknown or uninitialized platform.
      43             :   kUnknown = 0,
      44             : 
      45             :   //! Windows OS.
      46             :   kWindows,
      47             : 
      48             :   //! Other platform that is not Windows, most likely POSIX based.
      49             :   kOther,
      50             : 
      51             :   //! Linux OS.
      52             :   kLinux,
      53             :   //! GNU/Hurd OS.
      54             :   kHurd,
      55             : 
      56             :   //! FreeBSD OS.
      57             :   kFreeBSD,
      58             :   //! OpenBSD OS.
      59             :   kOpenBSD,
      60             :   //! NetBSD OS.
      61             :   kNetBSD,
      62             :   //! DragonFly BSD OS.
      63             :   kDragonFlyBSD,
      64             : 
      65             :   //! Haiku OS.
      66             :   kHaiku,
      67             : 
      68             :   //! Apple OSX.
      69             :   kOSX,
      70             :   //! Apple iOS.
      71             :   kIOS,
      72             :   //! Apple TVOS.
      73             :   kTVOS,
      74             :   //! Apple WatchOS.
      75             :   kWatchOS,
      76             : 
      77             :   //! Emscripten platform.
      78             :   kEmscripten,
      79             : 
      80             :   //! Maximum value of `Platform`.
      81             :   kMaxValue = kEmscripten,
      82             : 
      83             :   //! Platform detected at compile-time (platform of the host).
      84             :   kHost =
      85             : #if defined(_DOXYGEN)
      86             :     DETECTED_AT_COMPILE_TIME
      87             : #elif defined(__EMSCRIPTEN__)
      88             :     kEmscripten
      89             : #elif defined(_WIN32)
      90             :     kWindows
      91             : #elif defined(__linux__)
      92             :     kLinux
      93             : #elif defined(__gnu_hurd__)
      94             :     kHurd
      95             : #elif defined(__FreeBSD__)
      96             :     kFreeBSD
      97             : #elif defined(__OpenBSD__)
      98             :     kOpenBSD
      99             : #elif defined(__NetBSD__)
     100             :     kNetBSD
     101             : #elif defined(__DragonFly__)
     102             :     kDragonFlyBSD
     103             : #elif defined(__HAIKU__)
     104             :     kHaiku
     105             : #elif defined(__APPLE__) && TARGET_OS_OSX
     106             :     kOSX
     107             : #elif defined(__APPLE__) && TARGET_OS_TV
     108             :     kTVOS
     109             : #elif defined(__APPLE__) && TARGET_OS_WATCH
     110             :     kWatchOS
     111             : #elif defined(__APPLE__) && TARGET_OS_IPHONE
     112             :     kIOS
     113             : #else
     114             :     kOther
     115             : #endif
     116             : };
     117             : 
     118             : //! Platform ABI (application binary interface).
     119             : enum class PlatformABI : uint8_t {
     120             :   //! Unknown or uninitialied environment.
     121             :   kUnknown = 0,
     122             :   //! Microsoft ABI.
     123             :   kMSVC,
     124             :   //! GNU ABI.
     125             :   kGNU,
     126             :   //! Android Environment / ABI.
     127             :   kAndroid,
     128             :   //! Cygwin ABI.
     129             :   kCygwin,
     130             : 
     131             :   //! Maximum value of `PlatformABI`.
     132             :   kMaxValue,
     133             : 
     134             :   //! Host ABI detected at compile-time.
     135             :   kHost =
     136             : #if defined(_DOXYGEN)
     137             :     DETECTED_AT_COMPILE_TIME
     138             : #elif defined(_MSC_VER)
     139             :     kMSVC
     140             : #elif defined(__CYGWIN__)
     141             :     kCygwin
     142             : #elif defined(__MINGW32__) || defined(__GLIBC__)
     143             :     kGNU
     144             : #elif defined(__ANDROID__)
     145             :     kAndroid
     146             : #else
     147             :     kUnknown
     148             : #endif
     149             : };
     150             : 
     151             : //! Object format.
     152             : //!
     153             : //! \note AsmJit doesn't really use anything except \ref ObjectFormat::kUnknown and \ref ObjectFormat::kJIT at
     154             : //! the moment. Object file formats are provided for future extensibility and a possibility to generate object
     155             : //! files at some point.
     156             : enum class ObjectFormat : uint8_t {
     157             :   //! Unknown or uninitialized object format.
     158             :   kUnknown = 0,
     159             : 
     160             :   //! JIT code generation object, most likely \ref JitRuntime or a custom
     161             :   //! \ref Target implementation.
     162             :   kJIT,
     163             : 
     164             :   //! Executable and linkable format (ELF).
     165             :   kELF,
     166             :   //! Common object file format.
     167             :   kCOFF,
     168             :   //! Extended COFF object format.
     169             :   kXCOFF,
     170             :   //! Mach object file format.
     171             :   kMachO,
     172             : 
     173             :   //! Maximum value of `ObjectFormat`.
     174             :   kMaxValue
     175             : };
     176             : 
     177             : //! Represents an environment, which is usually related to a \ref Target.
     178             : //!
     179             : //! Environment has usually an 'arch-subarch-vendor-os-abi' format, which is sometimes called "Triple" (historically
     180             : //! it used to be 3 only parts) or "Tuple", which is a convention used by Debian Linux.
     181             : //!
     182             : //! AsmJit doesn't support all possible combinations or architectures and ABIs, however, it models the environment
     183             : //! similarly to other compilers for future extensibility.
     184             : class Environment {
     185             : public:
     186             :   //! \name Members
     187             :   //! \{
     188             : 
     189             :   //! Architecture.
     190             :   Arch _arch;
     191             :   //! Sub-architecture type.
     192             :   SubArch _subArch;
     193             :   //! Vendor type.
     194             :   Vendor _vendor;
     195             :   //! Platform.
     196             :   Platform _platform;
     197             :   //! Platform ABI.
     198             :   PlatformABI _platformABI;
     199             :   //! Object format.
     200             :   ObjectFormat _objectFormat;
     201             :   //! Reserved for future use, must be zero.
     202             :   uint8_t _reserved[2];
     203             : 
     204             :   //! \}
     205             : 
     206             :   //! \name Construction & Destruction
     207             :   //! \{
     208             : 
     209      109898 :   inline Environment() noexcept :
     210      109898 :     _arch(Arch::kUnknown),
     211      109898 :     _subArch(SubArch::kUnknown),
     212      109898 :     _vendor(Vendor::kUnknown),
     213      109898 :     _platform(Platform::kUnknown),
     214      109898 :     _platformABI(PlatformABI::kUnknown),
     215      109898 :     _objectFormat(ObjectFormat::kUnknown),
     216      109898 :     _reserved { 0, 0 } {}
     217             : 
     218             :   inline explicit Environment(
     219             :     Arch arch,
     220             :     SubArch subArch = SubArch::kUnknown,
     221             :     Vendor vendor = Vendor::kUnknown,
     222             :     Platform platform = Platform::kUnknown,
     223             :     PlatformABI abi = PlatformABI::kUnknown,
     224             :     ObjectFormat objectFormat = ObjectFormat::kUnknown) noexcept {
     225             : 
     226             :     init(arch, subArch, vendor, platform, abi, objectFormat);
     227             :   }
     228             : 
     229             :   inline Environment(const Environment& other) noexcept = default;
     230             : 
     231             :   //! Returns the host environment constructed from preprocessor macros defined by the compiler.
     232             :   //!
     233             :   //! The returned environment should precisely match the target host architecture, sub-architecture, platform,
     234             :   //! and ABI.
     235             :   static inline Environment host() noexcept {
     236             :     return Environment(Arch::kHost, SubArch::kHost, Vendor::kHost, Platform::kHost, PlatformABI::kHost, ObjectFormat::kUnknown);
     237             :   }
     238             : 
     239             :   //! \}
     240             : 
     241             :   //! \name Overloaded Operators
     242             :   //! \{
     243             : 
     244             :   inline Environment& operator=(const Environment& other) noexcept = default;
     245             : 
     246             :   inline bool operator==(const Environment& other) const noexcept { return  equals(other); }
     247             :   inline bool operator!=(const Environment& other) const noexcept { return !equals(other); }
     248             : 
     249             :   //! \}
     250             : 
     251             :   //! \name Accessors
     252             :   //! \{
     253             : 
     254             :   //! Tests whether the environment is not set up.
     255             :   //!
     256             :   //! Returns true if all members are zero, and thus unknown.
     257             :   inline bool empty() const noexcept {
     258             :     // Unfortunately compilers won't optimize fields are checked one by one...
     259             :     return _packed() == 0;
     260             :   }
     261             : 
     262             :   //! Tests whether the environment is initialized, which means it must have
     263             :   //! a valid architecture.
     264             :   inline bool isInitialized() const noexcept {
     265       27492 :     return _arch != Arch::kUnknown;
     266             :   }
     267             : 
     268             :   inline uint64_t _packed() const noexcept {
     269             :     uint64_t x;
     270             :     memcpy(&x, this, 8);
     271             :     return x;
     272             :   }
     273             : 
     274             :   //! Resets all members of the environment to zero / unknown.
     275             :   inline void reset() noexcept {
     276       27492 :     _arch = Arch::kUnknown;
     277       27492 :     _subArch = SubArch::kUnknown;
     278       27492 :     _vendor = Vendor::kUnknown;
     279       27492 :     _platform = Platform::kUnknown;
     280       27492 :     _platformABI = PlatformABI::kUnknown;
     281       27492 :     _objectFormat = ObjectFormat::kUnknown;
     282       27492 :     _reserved[0] = 0;
     283       27492 :     _reserved[1] = 0;
     284             :   }
     285             : 
     286             :   inline bool equals(const Environment& other) const noexcept {
     287             :     return _packed() == other._packed();
     288             :   }
     289             : 
     290             :   //! Returns the architecture.
     291      503352 :   inline Arch arch() const noexcept { return _arch; }
     292             :   //! Returns the sub-architecture.
     293             :   inline SubArch subArch() const noexcept { return _subArch; }
     294             :   //! Returns vendor.
     295             :   inline Vendor vendor() const noexcept { return _vendor; }
     296             :   //! Returns target's platform or operating system.
     297             :   inline Platform platform() const noexcept { return _platform; }
     298             :   //! Returns target's ABI.
     299             :   inline PlatformABI platformABI() const noexcept { return _platformABI; }
     300             :   //! Returns target's object format.
     301             :   inline ObjectFormat objectFormat() const noexcept { return _objectFormat; }
     302             : 
     303             :   inline void init(
     304             :     Arch arch,
     305             :     SubArch subArch = SubArch::kUnknown,
     306             :     Vendor vendor = Vendor::kUnknown,
     307             :     Platform platform = Platform::kUnknown,
     308             :     PlatformABI platformABI = PlatformABI::kUnknown,
     309             :     ObjectFormat objectFormat = ObjectFormat::kUnknown) noexcept {
     310             : 
     311             :     _arch = arch;
     312             :     _subArch = subArch;
     313             :     _vendor = vendor;
     314             :     _platform = platform;
     315             :     _platformABI = platformABI;
     316             :     _objectFormat = objectFormat;
     317             :     _reserved[0] = 0;
     318             :     _reserved[1] = 0;
     319             :   }
     320             : 
     321             :   inline bool isArchX86() const noexcept { return _arch == Arch::kX86; }
     322             :   inline bool isArchX64() const noexcept { return _arch == Arch::kX64; }
     323             :   inline bool isArchARM() const noexcept { return isArchARM(_arch); }
     324             :   inline bool isArchThumb() const noexcept { return isArchThumb(_arch); }
     325             :   inline bool isArchAArch64() const noexcept { return isArchAArch64(_arch); }
     326             :   inline bool isArchMIPS32() const noexcept { return isArchMIPS32(_arch); }
     327             :   inline bool isArchMIPS64() const noexcept { return isArchMIPS64(_arch); }
     328             :   inline bool isArchRISCV32() const noexcept { return _arch == Arch::kRISCV32; }
     329             :   inline bool isArchRISCV64() const noexcept { return _arch == Arch::kRISCV64; }
     330             : 
     331             :   //! Tests whether the architecture is 32-bit.
     332       37131 :   inline bool is32Bit() const noexcept { return is32Bit(_arch); }
     333             :   //! Tests whether the architecture is 64-bit.
     334       27492 :   inline bool is64Bit() const noexcept { return is64Bit(_arch); }
     335             : 
     336             :   //! Tests whether the architecture is little endian.
     337             :   inline bool isLittleEndian() const noexcept { return isLittleEndian(_arch); }
     338             :   //! Tests whether the architecture is big endian.
     339             :   inline bool isBigEndian() const noexcept { return isBigEndian(_arch); }
     340             : 
     341             :   //! Tests whether this architecture is of X86 family.
     342       74262 :   inline bool isFamilyX86() const noexcept { return isFamilyX86(_arch); }
     343             :   //! Tests whether this architecture family is ARM, THUMB, or AArch64.
     344           0 :   inline bool isFamilyARM() const noexcept { return isFamilyARM(_arch); }
     345             :   //! Tests whether this architecture family is AArch32 (ARM or THUMB).
     346             :   inline bool isFamilyAArch32() const noexcept { return isFamilyAArch32(_arch); }
     347             :   //! Tests whether this architecture family is AArch64.
     348           0 :   inline bool isFamilyAArch64() const noexcept { return isFamilyAArch64(_arch); }
     349             :   //! Tests whether this architecture family is MISP or MIPS64.
     350             :   inline bool isFamilyMIPS() const noexcept { return isFamilyMIPS(_arch); }
     351             :   //! Tests whether this architecture family is RISC-V (both 32-bit and 64-bit).
     352             :   inline bool isFamilyRISCV() const noexcept { return isFamilyRISCV(_arch); }
     353             : 
     354             :   //! Tests whether the environment platform is Windows.
     355       37131 :   inline bool isPlatformWindows() const noexcept { return _platform == Platform::kWindows; }
     356             : 
     357             :   //! Tests whether the environment platform is Linux.
     358           0 :   inline bool isPlatformLinux() const noexcept { return _platform == Platform::kLinux; }
     359             : 
     360             :   //! Tests whether the environment platform is Hurd.
     361             :   inline bool isPlatformHurd() const noexcept { return _platform == Platform::kHurd; }
     362             : 
     363             :   //! Tests whether the environment platform is Haiku.
     364             :   inline bool isPlatformHaiku() const noexcept { return _platform == Platform::kHaiku; }
     365             : 
     366             :   //! Tests whether the environment platform is any BSD.
     367             :   inline bool isPlatformBSD() const noexcept {
     368             :     return _platform == Platform::kFreeBSD ||
     369             :            _platform == Platform::kOpenBSD ||
     370           0 :            _platform == Platform::kNetBSD ||
     371             :            _platform == Platform::kDragonFlyBSD;
     372             :   }
     373             : 
     374             :   //! Tests whether the environment platform is any Apple platform (OSX, iOS, TVOS, WatchOS).
     375             :   inline bool isPlatformApple() const noexcept {
     376             :     return _platform == Platform::kOSX ||
     377             :            _platform == Platform::kIOS ||
     378           0 :            _platform == Platform::kTVOS ||
     379             :            _platform == Platform::kWatchOS;
     380             :   }
     381             : 
     382             :   //! Tests whether the ABI is MSVC.
     383       37131 :   inline bool isMSVC() const noexcept { return _platformABI == PlatformABI::kMSVC; }
     384             :   //! Tests whether the ABI is GNU.
     385             :   inline bool isGNU() const noexcept { return _platformABI == PlatformABI::kGNU; }
     386             : 
     387             :   //! Returns a calculated stack alignment for this environment.
     388             :   ASMJIT_API uint32_t stackAlignment() const noexcept;
     389             : 
     390             :   //! Returns a native register size of this architecture.
     391       54984 :   uint32_t registerSize() const noexcept { return registerSizeFromArch(_arch); }
     392             : 
     393             :   //! Sets the architecture to `arch`.
     394             :   inline void setArch(Arch arch) noexcept { _arch = arch; }
     395             :   //! Sets the sub-architecture to `subArch`.
     396             :   inline void setSubArch(SubArch subArch) noexcept { _subArch = subArch; }
     397             :   //! Sets the vendor to `vendor`.
     398             :   inline void setVendor(Vendor vendor) noexcept { _vendor = vendor; }
     399             :   //! Sets the platform to `platform`.
     400             :   inline void setPlatform(Platform platform) noexcept { _platform = platform; }
     401             :   //! Sets the ABI to `platformABI`.
     402             :   inline void setPlatformABI(PlatformABI platformABI) noexcept { _platformABI = platformABI; }
     403             :   //! Sets the object format to `objectFormat`.
     404       27422 :   inline void setObjectFormat(ObjectFormat objectFormat) noexcept { _objectFormat = objectFormat; }
     405             : 
     406             :   //! \}
     407             : 
     408             :   //! \name Static Utilities
     409             :   //! \{
     410             : 
     411             :   static inline bool isDefinedArch(Arch arch) noexcept {
     412             :     return uint32_t(arch) <= uint32_t(Arch::kMaxValue);
     413             :   }
     414             : 
     415             :   static inline bool isValidArch(Arch arch) noexcept {
     416       54984 :     return arch != Arch::kUnknown && uint32_t(arch) <= uint32_t(Arch::kMaxValue);
     417             :   }
     418             : 
     419             :   //! Tests whether the given architecture `arch` is 32-bit.
     420             :   static inline bool is32Bit(Arch arch) noexcept {
     421             :     return (uint32_t(arch) & uint32_t(Arch::k32BitMask)) == uint32_t(Arch::k32BitMask);
     422             :   }
     423             : 
     424             :   //! Tests whether the given architecture `arch` is 64-bit.
     425             :   static inline bool is64Bit(Arch arch) noexcept {
     426             :     return (uint32_t(arch) & uint32_t(Arch::k32BitMask)) == 0;
     427             :   }
     428             : 
     429             :   //! Tests whether the given architecture `arch` is little endian.
     430             :   static inline bool isLittleEndian(Arch arch) noexcept {
     431             :     return uint32_t(arch) < uint32_t(Arch::kBigEndian);
     432             :   }
     433             : 
     434             :   //! Tests whether the given architecture `arch` is big endian.
     435             :   static inline bool isBigEndian(Arch arch) noexcept {
     436             :     return uint32_t(arch) >= uint32_t(Arch::kBigEndian);
     437             :   }
     438             : 
     439             :   //! Tests whether the given architecture is Thumb or Thumb_BE.
     440             :   static inline bool isArchThumb(Arch arch) noexcept {
     441           0 :     return arch == Arch::kThumb || arch == Arch::kThumb_BE;
     442             :   }
     443             : 
     444             :   //! Tests whether the given architecture is ARM or ARM_BE.
     445             :   static inline bool isArchARM(Arch arch) noexcept {
     446           0 :     return arch == Arch::kARM || arch == Arch::kARM_BE;
     447             :   }
     448             : 
     449             :   //! Tests whether the given architecture is AArch64 or AArch64_BE.
     450             :   static inline bool isArchAArch64(Arch arch) noexcept {
     451           0 :     return arch == Arch::kAArch64 || arch == Arch::kAArch64_BE;
     452             :   }
     453             : 
     454             :   //! Tests whether the given architecture is MIPS32_LE or MIPS32_BE.
     455             :   static inline bool isArchMIPS32(Arch arch) noexcept {
     456             :     return arch == Arch::kMIPS32_LE || arch == Arch::kMIPS32_BE;
     457             :   }
     458             : 
     459             :   //! Tests whether the given architecture is MIPS64_LE or MIPS64_BE.
     460             :   static inline bool isArchMIPS64(Arch arch) noexcept {
     461             :     return arch == Arch::kMIPS64_LE || arch == Arch::kMIPS64_BE;
     462             :   }
     463             : 
     464             :   //! Tests whether the given architecture family is X86 or X64.
     465             :   static inline bool isFamilyX86(Arch arch) noexcept {
     466       74262 :     return arch == Arch::kX86 || arch == Arch::kX64;
     467             :   }
     468             : 
     469             :   //! Tests whether the given architecture family is ARM, THUMB, or AArch64.
     470           0 :   static inline bool isFamilyARM(Arch arch) noexcept {
     471           0 :     return isArchARM(arch) || isArchAArch64(arch) || isArchThumb(arch);
     472             :   }
     473             : 
     474             :   //! Tests whether the given architecture family is AArch32 (ARM or THUMB).
     475             :   static inline bool isFamilyAArch32(Arch arch) noexcept {
     476             :     return isArchARM(arch) || isArchThumb(arch);
     477             :   }
     478             : 
     479             :   //! Tests whether the given architecture family is AArch64.
     480             :   static inline bool isFamilyAArch64(Arch arch) noexcept {
     481             :     return isArchAArch64(arch);
     482             :   }
     483             : 
     484             :   //! Tests whether the given architecture family is MISP or MIPS64.
     485             :   static inline bool isFamilyMIPS(Arch arch) noexcept {
     486             :     return isArchMIPS32(arch) || isArchMIPS64(arch);
     487             :   }
     488             : 
     489             :   //! Tests whether the given architecture family is RISC-V (both 32-bit and 64-bit).
     490             :   static inline bool isFamilyRISCV(Arch arch) noexcept {
     491             :     return arch == Arch::kRISCV32 || arch == Arch::kRISCV64;
     492             :   }
     493             : 
     494             :   //! Returns a native general purpose register size from the given architecture.
     495             :   static inline uint32_t registerSizeFromArch(Arch arch) noexcept {
     496      396431 :     return is32Bit(arch) ? 4u : 8u;
     497             :   }
     498             : 
     499             :   //! \}
     500             : };
     501             : 
     502             : static_assert(sizeof(Environment) == 8,
     503             :               "Environment must occupy exactly 8 bytes.");
     504             : 
     505             : //! \}
     506             : 
     507             : ASMJIT_END_NAMESPACE
     508             : 
     509             : #endif // ASMJIT_CORE_ENVIRONMENT_H_INCLUDED
     510             : 
     511             : #endif // __PLUMED_HAS_ASMJIT

Generated by: LCOV version 1.16