TRLC Platform Library  1.0.0
Header-only C++ library for compile-time platform detection and abstraction
architecture.hpp
Go to the documentation of this file.
1 
64 #pragma once
65 
66 #include <cstddef> // For size_t
67 
68 #include "endianness.hpp" // For ByteOrder enum and endianness functions
69 
70 namespace trlc {
71 namespace platform {
72 
105 enum class CpuArchitecture : int {
106  unknown = 0,
107  x86,
108  x86_64,
109  arm_v6,
110  arm_v7,
111  arm_v8_32,
112  arm_v8_64,
113  mips,
114  mips_64,
115  powerpc,
116  powerpc_64,
117  risc_v_32,
118  risc_v_64,
119  sparc,
120  sparc_64
121 };
122 
170  const char* arch_name;
171 
185  constexpr bool is64Bit() const noexcept { return pointer_size_bits == 64; }
186 
200  constexpr bool is32Bit() const noexcept { return pointer_size_bits == 32; }
201 
214  constexpr bool isLittleEndian() const noexcept {
216  }
217 
238  constexpr bool supportsUnalignedAccess() const noexcept {
239  // x86/x64 and most modern ARM cores support unaligned access efficiently
244  }
245 
265  constexpr bool hasSimdSupport() const noexcept {
270  }
271 
289  constexpr bool isARM() const noexcept {
293  }
294 
310  constexpr bool isX86() const noexcept {
312  }
313 };
314 
315 namespace detail {
316 
322 // x86/x64 detection
323 #if defined(__x86_64__) || defined(__x86_64) || defined(__amd64__) || defined(__amd64) || \
324  defined(_M_X64)
326 #elif defined(__i386__) || defined(__i386) || defined(__i486__) || defined(__i586__) || \
327  defined(__i686__) || defined(_M_IX86)
328  return CpuArchitecture::x86;
329 
330 // ARM detection
331 #elif defined(__aarch64__) || defined(_M_ARM64)
333 #elif defined(__arm__) || defined(_M_ARM)
334  #if defined(__ARM_ARCH_8__) || defined(__ARM_ARCH_8A__)
336  #elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || \
337  defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__)
339  #elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || \
340  defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__)
342  #else
343  return CpuArchitecture::arm_v7; // Default to v7 for unknown ARM
344  #endif
345 
346 // MIPS detection
347 #elif defined(__mips__) || defined(__mips) || defined(__MIPS__)
348  #if defined(__mips64__) || defined(__mips64) || (_MIPS_SIM == _ABI64)
350  #else
351  return CpuArchitecture::mips;
352  #endif
353 
354 // PowerPC detection
355 #elif defined(__powerpc__) || defined(__powerpc) || defined(__ppc__) || defined(__ppc) || \
356  defined(_M_PPC)
357  #if defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__) || defined(_ARCH_PPC64)
359  #else
361  #endif
362 
363 // RISC-V detection
364 #elif defined(__riscv)
365  #if defined(__riscv_xlen) && (__riscv_xlen == 64)
367  #elif defined(__riscv_xlen) && (__riscv_xlen == 32)
369  #else
370  return CpuArchitecture::risc_v_64; // Default to 64-bit RISC-V
371  #endif
372 
373 // SPARC detection
374 #elif defined(__sparc__) || defined(__sparc)
375  #if defined(__sparc64__) || defined(__sparcv9)
377  #else
378  return CpuArchitecture::sparc;
379  #endif
380 
381 #else
383 #endif
384 }
385 
386 // Note: detectByteOrder() moved to endianness.hpp as getByteOrder()
387 
392 constexpr int detectPointerSize() noexcept {
393  constexpr auto arch = detectCpuArchitecture();
394  switch (arch) {
401  return 64;
402 
411  return 32;
412 
413  default:
414  return sizeof(void*) * 8; // Fallback to actual pointer size
415  }
416 }
417 
422 constexpr size_t detectCacheLineSize() noexcept {
423  constexpr auto arch = detectCpuArchitecture();
424  switch (arch) {
427  return 64; // Intel/AMD typical cache line size
428 
431  return 32; // Older ARM cores
432 
435  return 64; // Modern ARM cores
436 
439  return 128; // PowerPC typical cache line size
440 
447  return 64; // Common default
448 
449  default:
450  return 64; // Safe default for unknown architectures
451  }
452 }
453 
458 constexpr const char* getArchitectureName() noexcept {
459  constexpr auto arch = detectCpuArchitecture();
460  switch (arch) {
462  return "x86";
464  return "x86_64";
466  return "ARM v6";
468  return "ARM v7";
470  return "ARM v8 (32-bit)";
472  return "ARM v8 (64-bit)";
474  return "MIPS";
476  return "MIPS64";
478  return "PowerPC";
480  return "PowerPC64";
482  return "RISC-V 32";
484  return "RISC-V 64";
486  return "SPARC";
488  return "SPARC64";
489  default:
490  return "Unknown";
491  }
492 }
493 
494 } // namespace detail
495 
537 constexpr CpuArchitecture getCpuArchitecture() noexcept {
539 }
540 
541 // Note: getByteOrder() is provided by endianness.hpp
542 
590 constexpr ArchitectureInfo getArchitectureInfo() noexcept {
592  getByteOrder(), // Use getByteOrder() from endianness.hpp
596 }
597 
636 constexpr int getPointerSize() noexcept {
637  return detail::detectPointerSize();
638 }
639 
681 constexpr bool hasSimdSupport() noexcept {
682  constexpr auto arch = getCpuArchitecture();
683  return arch == CpuArchitecture::x86 || arch == CpuArchitecture::x86_64 ||
686 }
687 
728 constexpr bool hasVectorInstructions() noexcept {
729  // Vector instructions include SIMD and more advanced vector processing
730  constexpr auto arch = getCpuArchitecture();
731  return arch == CpuArchitecture::x86_64 || // SSE/AVX
732  arch == CpuArchitecture::arm_v8_64 || // NEON/SVE
733  arch == CpuArchitecture::risc_v_64; // RISC-V Vector Extension
734 }
735 
774 constexpr bool supportsCacheLineAlignment() noexcept {
775  // Most modern architectures benefit from cache line alignment
776  constexpr auto arch = getCpuArchitecture();
777  return arch != CpuArchitecture::unknown;
778 }
779 
813 constexpr bool is64BitArchitecture() noexcept {
814  return getPointerSize() == 64;
815 }
816 
849 constexpr bool is32BitArchitecture() noexcept {
850  return getPointerSize() == 32;
851 }
852 
853 } // namespace platform
854 } // namespace trlc
855 
856 // Preprocessor-only architecture detection (for use in #if directives)
857 #if defined(__x86_64__) || defined(__x86_64) || defined(__amd64__) || defined(__amd64) || \
858  defined(_M_X64)
859  #define TRLC_ARCH_X86_64_PP 1
860  #define TRLC_ARCH_64BIT_PP 1
861  #define TRLC_ARCH_X86_64 1
862  #define TRLC_ARCH_64BIT 1
863 #else
864  #define TRLC_ARCH_X86_64_PP 0
865  #define TRLC_ARCH_X86_64 0
866 #endif
867 
868 #if defined(__aarch64__) || defined(_M_ARM64)
869  #define TRLC_ARCH_ARM64_PP 1
870  #define TRLC_ARCH_64BIT_PP 1
871  #define TRLC_ARCH_ARM64 1
872  #define TRLC_ARCH_64BIT 1
873 #else
874  #define TRLC_ARCH_ARM64_PP 0
875  #define TRLC_ARCH_ARM64 0
876 #endif
877 
878 #if defined(__i386__) || defined(__i386) || defined(_M_IX86)
879  #define TRLC_ARCH_X86_PP 1
880  #define TRLC_ARCH_32BIT_PP 1
881  #define TRLC_ARCH_X86 1
882  #define TRLC_ARCH_32BIT 1
883 #else
884  #define TRLC_ARCH_X86_PP 0
885  #define TRLC_ARCH_X86 0
886 #endif
887 
888 #if defined(__arm__) || defined(_M_ARM)
889  #define TRLC_ARCH_ARM_PP 1
890  #define TRLC_ARCH_32BIT_PP 1
891  #define TRLC_ARCH_ARM 1
892  #define TRLC_ARCH_32BIT 1
893 #else
894  #define TRLC_ARCH_ARM_PP 0
895  #define TRLC_ARCH_ARM 0
896 #endif
897 
898 // Additional architecture family macros
899 #if defined(__mips__) || defined(__mips) || defined(__MIPS__)
900  #define TRLC_ARCH_MIPS 1
901 #else
902  #define TRLC_ARCH_MIPS 0
903 #endif
904 
905 #if defined(__powerpc__) || defined(__powerpc) || defined(__ppc__) || defined(__ppc) || \
906  defined(_M_PPC)
907  #define TRLC_ARCH_POWERPC 1
908 #else
909  #define TRLC_ARCH_POWERPC 0
910 #endif
911 
912 #if defined(__riscv)
913  #define TRLC_ARCH_RISCV 1
914 #else
915  #define TRLC_ARCH_RISCV 0
916 #endif
917 
918 #if defined(__sparc__) || defined(__sparc)
919  #define TRLC_ARCH_SPARC 1
920 #else
921  #define TRLC_ARCH_SPARC 0
922 #endif
923 
924 // Ensure we have consistent bit width detection
925 #ifndef TRLC_ARCH_64BIT_PP
926  #if defined(__LP64__) || defined(_WIN64) || \
927  (defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ == 8)
928  #define TRLC_ARCH_64BIT_PP 1
929  #define TRLC_ARCH_32BIT_PP 0
930  #define TRLC_ARCH_64BIT 1
931  #define TRLC_ARCH_32BIT 0
932  #else
933  #define TRLC_ARCH_64BIT_PP 0
934  #define TRLC_ARCH_32BIT_PP 1
935  #define TRLC_ARCH_64BIT 0
936  #define TRLC_ARCH_32BIT 1
937  #endif
938 #endif
939 
940 #ifndef TRLC_ARCH_32BIT_PP
941  #define TRLC_ARCH_32BIT_PP (!TRLC_ARCH_64BIT_PP)
942  #define TRLC_ARCH_32BIT (!TRLC_ARCH_64BIT)
943 #endif
944 
945 // Byte order macros (preprocessor compatible)
946 #if defined(__BYTE_ORDER__)
947  #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
948  #define TRLC_LITTLE_ENDIAN 1
949  #define TRLC_BIG_ENDIAN 0
950  #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
951  #define TRLC_LITTLE_ENDIAN 0
952  #define TRLC_BIG_ENDIAN 1
953  #else
954  #define TRLC_LITTLE_ENDIAN 0
955  #define TRLC_BIG_ENDIAN 0
956  #endif
957 #elif defined(__LITTLE_ENDIAN__) || defined(__ARMEL__)
958  #define TRLC_LITTLE_ENDIAN 1
959  #define TRLC_BIG_ENDIAN 0
960 #elif defined(__BIG_ENDIAN__) || defined(__ARMEB__)
961  #define TRLC_LITTLE_ENDIAN 0
962  #define TRLC_BIG_ENDIAN 1
963 #else
964  // Architecture-based endianness detection
965  #if TRLC_ARCH_X86 || TRLC_ARCH_X86_64 || TRLC_ARCH_ARM || TRLC_ARCH_ARM64 || TRLC_ARCH_RISCV
966  #define TRLC_LITTLE_ENDIAN 1
967  #define TRLC_BIG_ENDIAN 0
968  #elif TRLC_ARCH_SPARC || TRLC_ARCH_MIPS || TRLC_ARCH_POWERPC
969  #define TRLC_LITTLE_ENDIAN 0
970  #define TRLC_BIG_ENDIAN 1
971  #else
972  #define TRLC_LITTLE_ENDIAN 1 // Default to little endian
973  #define TRLC_BIG_ENDIAN 0
974  #endif
975 #endif
976 
977 // SIMD and vector capability macros (preprocessor compatible)
978 #if TRLC_ARCH_X86 || TRLC_ARCH_X86_64 || TRLC_ARCH_ARM || TRLC_ARCH_ARM64
979  #define TRLC_HAS_SIMD 1
980 #else
981  #define TRLC_HAS_SIMD 0
982 #endif
983 
984 #if TRLC_ARCH_X86_64 || TRLC_ARCH_ARM64 || TRLC_ARCH_RISCV
985  #define TRLC_HAS_VECTOR 1
986 #else
987  #define TRLC_HAS_VECTOR 0
988 #endif
Byte order detection and utilities for cross-platform development.
static int detectPointerSize()
Determines pointer size based on architecture.
static size_t detectCacheLineSize()
Determines typical cache line size for architecture.
static const char * getArchitectureName()
Gets human-readable architecture name.
static CpuArchitecture detectCpuArchitecture()
Detects CPU architecture using compiler predefined macros.
ByteOrder
Byte order enumeration.
Definition: endianness.hpp:33
@ little_endian
Little-endian (LSB first)
static bool hasSimdSupport()
static bool is32BitArchitecture()
static CpuArchitecture getCpuArchitecture()
static ArchitectureInfo getArchitectureInfo()
static int getPointerSize()
static bool is64BitArchitecture()
static ByteOrder getByteOrder()
Get the system's byte order.
Definition: endianness.hpp:159
static bool supportsCacheLineAlignment()
CpuArchitecture
CPU architecture enumeration.
@ x86_64
Intel/AMD x86-64 (64-bit) - Modern desktop/server processors.
@ arm_v6
ARM Architecture v6 - Older embedded systems (e.g., Raspberry Pi 1)
@ arm_v8_64
AArch64 (ARM v8 64-bit mode / ARM64) - Modern mobile, Apple Silicon.
@ risc_v_64
RISC-V (64-bit) - Open-source architecture, future systems.
@ mips_64
MIPS64 (64-bit) - High-performance MIPS systems.
@ sparc
SPARC (32-bit) - Legacy Sun/Oracle workstations.
@ powerpc_64
PowerPC64 (64-bit) - High-performance PowerPC systems.
@ arm_v8_32
AArch32 (ARM v8 32-bit mode) - Modern ARM in 32-bit mode.
@ x86
Intel/AMD x86 (32-bit) - Legacy desktop/server processors.
@ sparc_64
SPARC64 (64-bit) - Oracle/Sun servers and workstations.
@ unknown
Unknown or unsupported architecture.
@ risc_v_32
RISC-V (32-bit) - Open-source architecture, embedded systems.
@ powerpc
PowerPC (32-bit) - Legacy Apple computers, embedded systems.
@ arm_v7
ARM Architecture v7 - Mobile devices, embedded systems.
@ mips
MIPS (32-bit) - Embedded systems, older workstations.
static bool hasVectorInstructions()
static bool isX86() const
Checks if the architecture is x86-based.
size_t cache_line_size
Typical cache line size in bytes.
ByteOrder byte_order
Detected byte order (endianness)
static bool is64Bit() const
Checks if the architecture is 64-bit.
int pointer_size_bits
Pointer size in bits (32 or 64)
static bool supportsUnalignedAccess() const
Checks if the architecture supports unaligned memory access.
const char * arch_name
Human-readable architecture name.
static bool isLittleEndian() const
Checks if the architecture uses little-endian byte order.
static bool hasSimdSupport() const
Checks if the architecture supports SIMD instructions.
static bool is32Bit() const
Checks if the architecture is 32-bit.
CpuArchitecture architecture
Detected CPU architecture type.
static bool isARM() const
Checks if the architecture is ARM-based.