diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0690aa4 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +cmake_build/ diff --git a/.travis.yml b/.travis.yml index 8edbf1e..22b0d1e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,16 +1,81 @@ -sudo: required language: c -os: - - linux - - osx +sudo: false -compiler: - - clang - - gcc +cache: + directories: + - $HOME/cpu_features_archives + +matrix: + include: + - os: linux + compiler: gcc + env: + TOOLCHAIN=NATIVE + TARGET=native + - os: linux + compiler: clang + env: + TOOLCHAIN=NATIVE + TARGET=native + - os: osx + compiler: gcc + env: + TOOLCHAIN=NATIVE + TARGET=native + - os: osx + compiler: clang + env: + TOOLCHAIN=NATIVE + TARGET=native + # Toolchains for little-endian, 64-bit ARMv8 for GNU/Linux systems + - os: linux + env: + TOOLCHAIN=LINARO + TARGET=aarch64-linux-gnu + QEMU_ARCH=aarch64 + # Toolchains for little-endian, hard-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems + - os: linux + env: + TOOLCHAIN=LINARO + TARGET=arm-linux-gnueabihf + QEMU_ARCH=arm + # Toolchains for little-endian, 32-bit ARMv8 for GNU/Linux systems + - os: linux + env: + TOOLCHAIN=LINARO + TARGET=armv8l-linux-gnueabihf + QEMU_ARCH=arm + # Toolchains for little-endian, soft-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems + - os: linux + env: + TOOLCHAIN=LINARO + TARGET=arm-linux-gnueabi + QEMU_ARCH=arm + # Toolchains for big-endian, 64-bit ARMv8 for GNU/Linux systems + - os: linux + env: + TOOLCHAIN=LINARO + TARGET=aarch64_be-linux-gnu + QEMU_ARCH=DISABLED + # Toolchains for big-endian, hard-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems + - os: linux + env: + TOOLCHAIN=LINARO + TARGET=armeb-linux-gnueabihf + QEMU_ARCH=DISABLED + # Toolchains for big-endian, soft-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems + - os: linux + env: + TOOLCHAIN=LINARO + TARGET=armeb-linux-gnueabi + QEMU_ARCH=DISABLED + - os: linux + env: + TOOLCHAIN=CODESCAPE + TARGET=mips-mti-linux-gnu + QEMU_ARCH=DISABLED script: - cmake --version - - cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON -H. -Bcmake_build - - cmake --build cmake_build --target all - - CTEST_OUTPUT_ON_FAILURE=1 cmake --build cmake_build --target test + - bash -e -x ./scripts/run_integration.sh diff --git a/cmake/mips32-linux-gcc.cmake b/cmake/mips32-linux-gcc.cmake new file mode 100644 index 0000000..dcfab7c --- /dev/null +++ b/cmake/mips32-linux-gcc.cmake @@ -0,0 +1,34 @@ +set(CMAKE_SYSTEM_NAME "Linux") +set(CMAKE_SYSTEM_PROCESSOR "mips32") + +if (ENABLE_DSPR2 AND ENABLE_MSA) + message(FATAL_ERROR "ENABLE_DSPR2 and ENABLE_MSA cannot be combined.") +endif () + +if (ENABLE_DSPR2) + set(HAVE_DSPR2 1 CACHE BOOL "" FORCE) + set(MIPS_CFLAGS "-mdspr2") + set(MIPS_CXXFLAGS "-mdspr2") +elseif (ENABLE_MSA) + set(HAVE_MSA 1 CACHE BOOL "" FORCE) + set(MIPS_CFLAGS "-mmsa") + set(MIPS_CXXFLAGS "-mmsa") +endif () + +if ("${MIPS_CPU}" STREQUAL "") + set(MIPS_CFLAGS "${MIPS_CFLAGS} -mips32r2") + set(MIPS_CXXFLAGS "${MIPS_CXXFLAGS} -mips32r2") +elseif ("${MIPS_CPU}" STREQUAL "p5600") + set(P56_FLAGS "-mips32r5 -mload-store-pairs -msched-weight -mhard-float -mfp64") + set(MIPS_CFLAGS "${MIPS_CFLAGS} ${P56_FLAGS}") + set(MIPS_CXXFLAGS "${MIPS_CXXFLAGS} ${P56_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "-mfp64 ${CMAKE_EXE_LINKER_FLAGS}") +endif () + +set(CMAKE_C_COMPILER ${CROSS}gcc) +set(CMAKE_CXX_COMPILER ${CROSS}g++) +set(AS_EXECUTABLE ${CROSS}as) +set(CMAKE_C_COMPILER_ARG1 "-EL ${MIPS_CFLAGS}") +set(CMAKE_CXX_COMPILER_ARG1 "-EL ${MIPS_CXXFLAGS}") + +set(THREADS_PTHREAD_ARG "2" CACHE STRING "Forcibly set by CMakeLists.txt." FORCE) diff --git a/scripts/run_integration.sh b/scripts/run_integration.sh new file mode 100755 index 0000000..23755ef --- /dev/null +++ b/scripts/run_integration.sh @@ -0,0 +1,174 @@ +#!/bin/bash + +readonly SCRIPT_FOLDER=$(cd -P -- "$(dirname -- "$0")" && pwd -P) +readonly PROJECT_FOLDER="${SCRIPT_FOLDER}/.." +readonly ARCHIVE_FOLDER=~/cpu_features_archives +readonly QEMU_INSTALL=${ARCHIVE_FOLDER}/qemu +readonly DEFAULT_CMAKE_ARGS=" -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON" + +function extract() { + case $1 in + *.tar.bz2) tar xjf "$1" ;; + *.tar.xz) tar xJf "$1" ;; + *.tar.gz) tar xzf "$1" ;; + *) + echo "don't know how to extract '$1'..." + exit 1 + esac +} + +function unpackifnotexists() { + mkdir -p "${ARCHIVE_FOLDER}" + cd "${ARCHIVE_FOLDER}" || exit + local URL=$1 + local RELATIVE_FOLDER=$2 + local DESTINATION="${ARCHIVE_FOLDER}/${RELATIVE_FOLDER}" + if [[ ! -d "${DESTINATION}" ]] ; then + local ARCHIVE_NAME=$(echo ${URL} | sed 's/.*\///') + test -f "${ARCHIVE_NAME}" || wget -q "${URL}" + extract "${ARCHIVE_NAME}" + fi +} + +function installqemuifneeded() { + local VERSION=${QEMU_VERSION:=2.11.1} + local ARCHES=${QEMU_ARCHES:=arm aarch64 i386 x86_64 mips mipsel} + local TARGETS=${QEMU_TARGETS:=$(echo "$ARCHES" | sed 's#$# #;s#\([^ ]*\) #\1-linux-user #g')} + + if echo "${VERSION} ${TARGETS}" | cmp --silent ${QEMU_INSTALL}/.build -; then + echo "qemu ${VERSION} up to date!" + return 0 + fi + + echo "VERSION: ${VERSION}" + echo "TARGETS: ${TARGETS}" + + rm -rf ${QEMU_INSTALL} + + # Checking for a tarball before downloading makes testing easier :-) + local QEMU_URL="http://wiki.qemu-project.org/download/qemu-${VERSION}.tar.xz" + local QEMU_FOLDER="qemu-${VERSION}" + unpackifnotexists ${QEMU_URL} ${QEMU_FOLDER} + cd ${QEMU_FOLDER} || exit + + ./configure \ + --prefix="${QEMU_INSTALL}" \ + --target-list="${TARGETS}" \ + --disable-docs \ + --disable-sdl \ + --disable-gtk \ + --disable-gnutls \ + --disable-gcrypt \ + --disable-nettle \ + --disable-curses \ + --static + + make -j4 + make install + + echo "$VERSION $TARGETS" > ${QEMU_INSTALL}/.build +} + +function assert_defined(){ + local VALUE=${1} + : "${VALUE?"${1} needs to be defined"}" +} + +function integrate() { + cd "${PROJECT_FOLDER}" || exit + cmake -H. -B"${BUILD_DIR}" ${DEFAULT_CMAKE_ARGS} ${CMAKE_ADDITIONAL_ARGS} + cmake --build "${BUILD_DIR}" --target all + + if [[ -n "${QEMU_ARCH}" ]]; then + if [[ "${QEMU_ARCH}" == "DISABLED" ]]; then + QEMU="true || " + else + installqemuifneeded + QEMU="${QEMU_INSTALL}/bin/qemu-${QEMU_ARCH} ${QEMU_ARGS}" + fi + else + QEMU="" + fi + # Run tests + for test_binary in ${BUILD_DIR}/test/*_test; do ${QEMU} ${test_binary}; done + # Run demo program + ${QEMU} "${BUILD_DIR}/list_cpu_features" +} + +function expand_linaro_config() { + assert_defined TARGET + local LINARO_ROOT_URL=https://releases.linaro.org/components/toolchain/binaries/7.2-2017.11 + + local GCC_URL=${LINARO_ROOT_URL}/${TARGET}/gcc-linaro-7.2.1-2017.11-x86_64_${TARGET}.tar.xz + local GCC_RELATIVE_FOLDER="gcc-linaro-7.2.1-2017.11-x86_64_${TARGET}" + unpackifnotexists "${GCC_URL}" "${GCC_RELATIVE_FOLDER}" + + local SYSROOT_URL=${LINARO_ROOT_URL}/${TARGET}/sysroot-glibc-linaro-2.25-2017.11-${TARGET}.tar.xz + local SYSROOT_RELATIVE_FOLDER=sysroot-glibc-linaro-2.25-2017.11-${TARGET} + unpackifnotexists "${SYSROOT_URL}" "${SYSROOT_RELATIVE_FOLDER}" + + local SYSROOT_FOLDER=${ARCHIVE_FOLDER}/${SYSROOT_RELATIVE_FOLDER} + local GCC_FOLDER=${ARCHIVE_FOLDER}/${GCC_RELATIVE_FOLDER} + + CMAKE_ADDITIONAL_ARGS+=" -DCMAKE_SYSROOT=${SYSROOT_FOLDER}" + CMAKE_ADDITIONAL_ARGS+=" -DCMAKE_C_COMPILER=${GCC_FOLDER}/bin/${TARGET}-gcc" + CMAKE_ADDITIONAL_ARGS+=" -DCMAKE_CXX_COMPILER=${GCC_FOLDER}/bin/${TARGET}-g++" + + CMAKE_ADDITIONAL_ARGS+=" -DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER" + CMAKE_ADDITIONAL_ARGS+=" -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY" + CMAKE_ADDITIONAL_ARGS+=" -DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ONLY" + + QEMU_ARGS+=" -L ${SYSROOT_FOLDER}" + QEMU_ARGS+=" -E LD_LIBRARY_PATH=/lib" +} + +function expand_codescape_config() { + assert_defined TARGET + local FLAVOUR=${QEMU_ARCH}-r2-hard + local DATE=2016.05-03 + local CODESCAPE_URL=http://codescape-mips-sdk.imgtec.com/components/toolchain/${DATE}/Codescape.GNU.Tools.Package.${DATE}.for.MIPS.MTI.Linux.CentOS-5.x86_64.tar.gz + + local GCC_URL=${CODESCAPE_URL} + local GCC_RELATIVE_FOLDER=${TARGET}/${DATE} + unpackifnotexists "${GCC_URL}" "${GCC_RELATIVE_FOLDER}" + + local SYSROOT_URL=${CODESCAPE_URL} + local SYSROOT_FOLDER=${ARCHIVE_FOLDER}/${GCC_RELATIVE_FOLDER}/sysroot/${FLAVOUR} + unpackifnotexists "${SYSROOT_URL}" "${SYSROOT_RELATIVE_FOLDER}" + + CMAKE_ADDITIONAL_ARGS+=" -DENABLE_MSA=1" + CMAKE_ADDITIONAL_ARGS+=" -DMIPS_CPU=p5600" + CMAKE_ADDITIONAL_ARGS+=" -DCMAKE_TOOLCHAIN_FILE=cmake/mips32-linux-gcc.cmake" + CMAKE_ADDITIONAL_ARGS+=" -DCROSS=${TARGET}-" + CMAKE_ADDITIONAL_ARGS+=" -DCMAKE_FIND_ROOT_PATH=${ARCHIVE_FOLDER}/${GCC_RELATIVE_FOLDER}" + + QEMU_ARGS+=" -L ${SYSROOT_FOLDER}" + QEMU_ARGS+=" -E LD_LIBRARY_PATH=/lib" + QEMU_ARGS+=" -cpu P5600" +} + +function expand_environment_and_integrate() { + assert_defined PROJECT_FOLDER + assert_defined TARGET + + BUILD_DIR="${PROJECT_FOLDER}/cmake_build/${TARGET}" + mkdir -p "${BUILD_DIR}" + + CMAKE_ADDITIONAL_ARGS="" + QEMU_ARGS="" + + case ${TOOLCHAIN} in + LINARO) expand_linaro_config ;; + CODESCAPE) expand_codescape_config ;; + NATIVE) QEMU_ARCH="" ;; + *) + echo "Unknown toolchain '${TOOLCHAIN}'..." + exit 1 + esac + integrate +} + +if [ "${CONTINUOUS_INTEGRATION}" = "true" ]; then + QEMU_ARCHES=${QEMU_ARCH} + expand_environment_and_integrate +fi diff --git a/scripts/test_integration.sh b/scripts/test_integration.sh new file mode 100755 index 0000000..c98ed06 --- /dev/null +++ b/scripts/test_integration.sh @@ -0,0 +1,84 @@ +source "$(dirname -- "$0")"/run_integration.sh + +# Toolchains for little-endian, 64-bit ARMv8 for GNU/Linux systems +function set_aarch64-linux-gnu() { + TOOLCHAIN=LINARO + TARGET=aarch64-linux-gnu + QEMU_ARCH=aarch64 +} + +# Toolchains for little-endian, hard-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems +function set_arm-linux-gnueabihf() { + TOOLCHAIN=LINARO + TARGET=arm-linux-gnueabihf + QEMU_ARCH=arm +} + +# Toolchains for little-endian, 32-bit ARMv8 for GNU/Linux systems +function set_armv8l-linux-gnueabihf() { + TOOLCHAIN=LINARO + TARGET=armv8l-linux-gnueabihf + QEMU_ARCH=arm +} + +# Toolchains for little-endian, soft-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems +function set_arm-linux-gnueabi() { + TOOLCHAIN=LINARO + TARGET=arm-linux-gnueabi + QEMU_ARCH=arm +} + +# Toolchains for big-endian, 64-bit ARMv8 for GNU/Linux systems +function set_aarch64_be-linux-gnu() { + TOOLCHAIN=LINARO + TARGET=aarch64_be-linux-gnu + QEMU_ARCH="DISABLED" +} + +# Toolchains for big-endian, hard-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems +function set_armeb-linux-gnueabihf() { + TOOLCHAIN=LINARO + TARGET=armeb-linux-gnueabihf + QEMU_ARCH="DISABLED" +} + +# Toolchains for big-endian, soft-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems +function set_armeb-linux-gnueabi() { + TOOLCHAIN=LINARO + TARGET=armeb-linux-gnueabi + QEMU_ARCH="DISABLED" +} + + +function set_mips() { + TOOLCHAIN=CODESCAPE + TARGET=mips-mti-linux-gnu + QEMU_ARCH="DISABLED" +} + +function set_native() { + TOOLCHAIN=NATIVE + TARGET=native + QEMU_ARCH="" +} + +ENVIRONMENTS=" + set_aarch64-linux-gnu + set_arm-linux-gnueabihf + set_armv8l-linux-gnueabihf + set_arm-linux-gnueabi + set_aarch64_be-linux-gnu + set_armeb-linux-gnueabihf + set_armeb-linux-gnueabi + set_native + set_mips +" + +# ENVIRONMENTS=" +# set_mips +# " + +for SET_ENVIRONMENT in ${ENVIRONMENTS}; do + ${SET_ENVIRONMENT} + expand_environment_and_integrate +done