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