From e6bae918dd5a0b95fce7163f8e027a5255d9971c Mon Sep 17 00:00:00 2001 From: melonedo <44501064+melonedo@users.noreply.github.com> Date: Fri, 21 Apr 2023 16:31:42 +0800 Subject: [PATCH 1/2] Upstream 2023 (#32) * gollvm: add linux RISC-V support This patch sets up the C-ABI oracle for the RISC-V linux platform. The main changes are: 1. The C calling convention is used to identify this platform. 2. C-ABI oracle and compile options are set for RISC-V linux. 3. The ABI is hardcoded as lp64d on RISC-V linux. Change-Id: Ibe4f82623822800cb10451f44b6f9ac60eceb2c4 * gollvm: support building on RISC-V linux This patch adds relevant flags for building on RISC-V linux platform, its C-ABI setup is on another patch. Change-Id: I8e3e081bb2fffcc4cc2bbfa29b9d35e7fd98e853 --------- Co-authored-by: Qihan Cai Co-authored-by: melonedo --- CMakeLists.txt | 7 +- README.md | 55 ++- bridge/go-llvm-cabi-oracle.cpp | 231 ++++++++++ bridge/go-llvm-cabi-oracle.h | 14 + cmake/modules/AutoGenGo.cmake | 7 +- cmake/modules/GoVars.cmake | 8 + cmake/modules/LibbacktraceUtils.cmake | 7 + cmake/modules/LibffiUtils.cmake | 10 +- driver/ArchCpusAttrs.h | 141 +++--- driver/CompileGo.cpp | 10 +- driver/Driver.cpp | 4 - driver/GccUtils.cpp | 10 + driver/GnuTools.cpp | 3 + driver/IntegAssembler.cpp | 2 + driver/LinuxToolChain.cpp | 4 + libgo/CMakeLists.txt | 12 +- tools/capture-fcn-attributes.go | 1 + .../BackendCore/BackendCABIOracleTests.cpp | 427 ++++++++++++++++++ 18 files changed, 882 insertions(+), 71 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2561f8b..b8f20d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,6 +18,10 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules") set(GOLLVM_USE_SPLIT_STACK ON CACHE BOOL "use split stack by default") set(GOLLVM_DEFAULT_LINKER gold CACHE STRING "default linker for Go links") +string(REGEX REPLACE "-" " " lht_components ${LLVM_DEFAULT_TARGET_TRIPLE}) +separate_arguments(lht_components) +list(GET lht_components 0 llarch) + include(CmakeUtils) include(AddGollvm) @@ -40,9 +44,6 @@ set(EXTCC "CC=${CMAKE_C_COMPILER}" "CXX=${CMAKE_CXX_COMPILER}") set(gollvm_binroot "${CMAKE_CURRENT_BINARY_DIR}") # Set MPN path according to the target processor -string(REGEX REPLACE "-" " " lht_components ${LLVM_DEFAULT_TARGET_TRIPLE}) -separate_arguments(lht_components) -list(GET lht_components 0 llarch) if( ${llarch} STREQUAL "x86_64" ) set(MPN_PATH "x86_64 generic") diff --git a/README.md b/README.md index 1ba6551..f2278a7 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ source tree, then within the LLVM tree you check out additional git repos. * [Invoking cmake and ninja](#cmakeninja) * [Installing gollvm](#installing) * [Using an installed copy of gollvm](#using) + * [Crosscompiling gollvm](#crosscompiling) * [Information for gollvm developers](#developers) [FAQ](#FAQ) @@ -120,6 +121,58 @@ hi mom! % ``` +## Crosscompiling gollvm +You need a working version of gollvm on host system to cross compile. The following script will build and install gollvm on a cross compile system. + +``` +#!/bin/bash +set -e +mkdir -p build +cd build + +RISCV=$HOME/toolchain +SOURCE=$HOME/llvm-project/llvm +TRIPLE=riscv64-unknown-linux-gnu +INSTALL=/tmp/gollvm-install + +# host +cmake -G Ninja -S $SOURCE -B build-x86 \ + -DCMAKE_INSTALL_PREFIX=install-x86 \ + -DCMAKE_BUILD_TYPE=Debug \ + -DLLVM_USE_LINKER=bfd \ + -DGOLLVM_DEFAULT_LINKER=bfd \ + -DLLVM_TARGET_ARCH="X86-64,RISCV64" \ + -DLLVM_TARGETS_TO_BUILD="X86;RISCV" + +# crosscompile +cmake -G Ninja -S $SOURCE -B build-riscv \ + -DCMAKE_INSTALL_PREFIX=$INSTALL \ + -DCMAKE_BUILD_TYPE=Debug \ + -DLLVM_USE_LINKER=bfd \ + -DGOLLVM_DEFAULT_LINKER=bfd \ + -DCMAKE_CROSSCOMPILING=True \ + -DLLVM_TARGET_ARCH=RISCV64 \ + -DLLVM_DEFAULT_TARGET_TRIPLE=$TRIPLE \ + -DLLVM_TARGETS_TO_BUILD=RISCV \ + -DCMAKE_C_COMPILER=$RISCV/bin/$TRIPLE-gcc \ + -DCMAKE_CXX_COMPILER=$RISCV/bin/$TRIPLE-g++ \ + -DLLVM_TABLEGEN=$PWD/build-x86/bin/llvm-tblgen \ + -DGOLLVM_DRIVER_DIR=$PWD/build-x86/bin \ + -DGOLLVM_EXTRA_GOCFLAGS="--target=$TRIPLE \ + --gcc-toolchain=$RISCV/ \ + --sysroot=$RISCV/sysroot" \ + -DGOLLVM_USE_SPLIT_STACK=OFF \ + -DCMAKE_C_FLAGS=-latomic \ + -DCMAKE_CXX_FLAGS=-latomic + + +# build gollvm crosscompiler +ninja -C build-x86 llvm-goc llvm-goc-token llvm-godumpspec + +# cross compile gollvm, go tools and install +ninja -C build-riscv install-gollvm +``` + # Information for gollvm developers ## Source code structure @@ -269,7 +322,7 @@ inlining, vectorization, register allocation, etc. ## Which architectures and operating systems are supported for gollvm? -Gollvm is currently supported only for x86_64 and aarch64 Linux. +Gollvm is currently supported only for x86_64, aarch64 and riscv64 Linux. ## How does the gollvm runtime differ from the main Go runtime? diff --git a/bridge/go-llvm-cabi-oracle.cpp b/bridge/go-llvm-cabi-oracle.cpp index 7ba851f..7eb9925 100644 --- a/bridge/go-llvm-cabi-oracle.cpp +++ b/bridge/go-llvm-cabi-oracle.cpp @@ -141,6 +141,7 @@ class EightByteInfo { void incorporateScalar(Btype *bt); void determineABITypesForARM_AAPCS(); void determineABITypesForX86_64_SysV(); + void determineABITypesForRISC_V(); TypeManager *tm() const { return typeManager_; } }; @@ -160,6 +161,9 @@ EightByteInfo::EightByteInfo(Btype *bt, TypeManager *tmgr) determineABITypesForARM_AAPCS(); } break; + case gollvm::driver::CallingConvId::RISCV64_C: + determineABITypesForRISC_V(); + break; default: llvm::errs() << "unsupported gollvm::driver::CallingConvId " << static_cast(cconv) << "\n"; break; @@ -491,6 +495,79 @@ void EightByteInfo::determineABITypesForX86_64_SysV() ebrs_[0].abiDirectType = tm()->llvmDoubleType(); } +// Select the appropriate abi type for each eight-byte region within +// an EightByteInfo. Pure floating point types are mapped onto float, +// double, or <2 x float> (a vector type), integer types (or something +// that is a mix of integer and non-integer) are mapped onto the +// appropriately sized integer type. +// +// Problems arise in the code below when dealing with structures with +// constructs that inject additional padding. For example, consider +// the following struct passed by value: +// +// struct { +// f1 int8 +// f2 [0]uint64 +// f3 int8 +// } +// +// Without taking into account the over-alignment of field f3, we would +// wind up with two regions, each with type int8. This in itself is not so +// bad, but creating a struct from these two types (via ::computeABIStructType) +// would give us { int8, int8 }, in which the second field doesn't have +// the correct alignment. Work around this by checking for such situations +// and promoting the type of the first EBR to 64 bits. +// +void EightByteInfo::determineABITypesForRISC_V() { + // In the direct case, ebrs_.size() cannot be greater than 2 because + // parameters larger than 16 bytes are passed indirectly. + assert(ebrs_.size() <= 2); + unsigned intRegions = 0; + unsigned floatRegions = 0; + for (auto &ebr : ebrs_) { + if (ebr.abiDirectType != nullptr) + continue; + TypDisp regionDisp = ebr.getRegionTypDisp(); + if (regionDisp == FlavSSE) { + // Case 1: two floats -> two float structs + if (ebr.types.size() == 2) { + assert(ebr.types[0] == tm()->llvmDoubleType() || + ebr.types[0] == tm()->llvmFloatType() || + ebr.types[1] == tm()->llvmDoubleType() || + ebr.types[1] == tm()->llvmFloatType()); + ebr.abiDirectType = + tm()->makeLLVMTwoElementStructType(ebr.types[0], ebr.types[1]); + } else if (ebr.types.size() == 1) { + assert(ebr.types[0] == tm()->llvmDoubleType() || + ebr.types[0] == tm()->llvmFloatType()); + ebr.abiDirectType = ebr.types[0]; + } else { + assert(false && "this should never happen"); + } + floatRegions += 1; + } else { + unsigned nel = ebr.offsets.size(); + unsigned bytes = ebr.offsets[nel - 1] - ebr.offsets[0] + + tm()->llvmTypeSize(ebr.types[nel - 1]); + assert(bytes && bytes <= 8); + // Preserve pointerness for the use of GC. + // TODO: this assumes pointer is 8 byte, so we never pack pointer + // and other stuff together. + if (ebr.types[0]->isPointerTy()) + ebr.abiDirectType = tm()->llvmPtrType(); + else + ebr.abiDirectType = tm()->llvmArbitraryIntegerType(bytes); + intRegions += 1; + } + } + + // See the example above for more on why this is needed. + if (intRegions == 2 && ebrs_[0].abiDirectType->isIntegerTy()) + ebrs_[0].abiDirectType = tm()->llvmArbitraryIntegerType(8); + else if (floatRegions == 2 && ebrs_[0].abiDirectType == tm()->llvmFloatType()) + ebrs_[0].abiDirectType = tm()->llvmDoubleType(); +} + //...................................................................... llvm::Type *CABIParamInfo::computeABIStructType(TypeManager *tm) const @@ -556,6 +633,10 @@ class ABIState { availIntRegs_ = 8; availSIMDFPRegs_ = 8; break; + case gollvm::driver::CallingConvId::RISCV64_C: + availIntRegs_ = 8; + availFloatRegs_ = 8; + break; default: llvm::errs() << "unsupported gollvm::driver::CallingConvId " << static_cast(cconv) << "\n"; break; @@ -578,6 +659,11 @@ class ABIState { availSIMDFPRegs_ = t; argCount_ += 1; } + void addDirectFloatArg() { + if (availFloatRegs_) + availFloatRegs_ -= 1; + argCount_ += 1; + } void addIndirectArg() { argCount_ += 1; } void addIndirectReturn() { if (availIntRegs_) @@ -591,6 +677,7 @@ class ABIState { unsigned availIntRegs() const { return availIntRegs_; } unsigned availSSERegs() const { return availSSERegs_; } unsigned availSIMDFPRegs() const { return availSIMDFPRegs_; } + unsigned availFloatRegs() const { return availFloatRegs_; } void clearAvailIntRegs() { availIntRegs_ = 0; } void clearAvailSIMDFPRegs() { availSIMDFPRegs_ = 0; } @@ -598,6 +685,7 @@ class ABIState { unsigned availIntRegs_; unsigned availSSERegs_; unsigned availSIMDFPRegs_; + unsigned availFloatRegs_; unsigned argCount_; }; @@ -652,6 +740,10 @@ void CABIOracle::setCC() case gollvm::driver::CallingConvId::ARM_AAPCS: cc_ = std::unique_ptr(new CABIOracleARM_AAPCS(typeManager_)); break; + case gollvm::driver::CallingConvId::RISCV64_C: + cc_ = std::unique_ptr( + new CABIOracleRISC_V(typeManager_)); + break; default: llvm::errs() << "unsupported gollvm::driver::CallingConvId " << static_cast(ccID_) << "\n"; break; @@ -1158,3 +1250,142 @@ CABIParamInfo CABIOracleARM_AAPCS::analyzeABIReturn(Btype *resultType, } //...................................................................... + +CABIOracleRISC_V::CABIOracleRISC_V(TypeManager *typeManager) + : CABIOracleArgumentAnalyzer(typeManager) {} + +CABIParamDisp CABIOracleRISC_V::classifyArgType(Btype *btype) { + int64_t sz = tm_->typeSize(btype); + return (sz == 0 ? ParmIgnore : ((sz <= 16) ? ParmDirect : ParmIndirect)); +} + +// Given the number of registers that we think a param is going to consume, and +// a state object storing the registers used so far, canPassDirectly() makes a +// decision as to whether a given param can be passed directly in registers vs +// in memory. +// +// Note the first clause, "if (regsInt + regsSIMDFP == 1) return true". This may +// seem counter-intuitive (why no check against the state object?), but this way +// of doing things is the convention used by other front ends (e.g. clang). What +// is happening here is that for larger aggregate/array params (things that +// don't fit into a single register), we'll make the pass-through-memory +// semantics explicit in the function signature and generate the explict code to +// copy things into memory. For params that do fit into a single register, +// however, we just leave them all as by-value parameters and then assume that +// the back end will do the right thing (e.g. pass the first few in registers +// and then the remaining ones in memory). +// +// Doing things this way has performance advantages in that the middle-end +// (all of the machine-independent LLVM optimization passes) won't have +// to deal with the additional chunks of stack memory and code to copy +// things onto and off of the stack (not to mention the aliasing concerns +// when a local variable's address is taken and then passed in a function +// call). + +bool CABIOracleRISC_V::canPassDirectly(unsigned regsInt, unsigned regsFloat, + ABIState &state) { + if (regsInt + regsFloat == 1) // see comment above + return true; + if (regsInt <= state.availIntRegs() && regsFloat <= state.availFloatRegs()) + return true; + return false; +} + +CABIParamInfo CABIOracleRISC_V::analyzeABIParam(Btype *paramType, + ABIState &state) { + llvm::Type *ptyp = paramType->type(); + + // The only situations in which we should be seeing AuxT types here is + // in cases where we're analyzing the signatures of builtin functions, + // meaning that there should be no structures or arrays. + assert(paramType->flavor() != Btype::AuxT || ptyp->isVoidTy() || + !(ptyp->isStructTy() || ptyp->isArrayTy() || ptyp->isVectorTy() || + ptyp->isEmptyTy() || ptyp->isIntegerTy(8) || ptyp->isIntegerTy(16))); + + CABIParamDisp pdisp = classifyArgType(paramType); + + if (pdisp == ParmIgnore) { + // Empty struct or array + llvm::Type *voidType = tm_->llvmVoidType(); + return CABIParamInfo(voidType, ParmIgnore, AttrNone, -1); + } + + int sigOff = state.argCount(); + + if (pdisp == ParmIndirect) { + // Value will be passed in memory on stack. + // Stack is always in address space 0. + llvm::Type *ptrTyp = llvm::PointerType::get(ptyp, 0); + state.addIndirectArg(); + return CABIParamInfo(ptrTyp, ParmIndirect, AttrByVal, sigOff); + } + + // Figure out what to do in the direct case + assert(pdisp == ParmDirect); + EightByteInfo ebi(paramType, tm_); + + // Figure out how many registers it would take to pass this parm directly + unsigned regsInt = 0, regsFloat = 0; + ebi.getRegisterRequirements(®sInt, ®sFloat); + + // Make direct/indirect decision + CABIParamAttr attr = AttrNone; + if (canPassDirectly(regsInt, regsFloat, state)) { + std::vector abiTypes; + for (auto &ebr : ebi.regions()) { + abiTypes.push_back(ebr.abiDirectType); + if (ebr.attr != AttrNone) { + assert(attr == AttrNone || attr == ebr.attr); + attr = ebr.attr; + } + if (ebr.getRegionTypDisp() == FlavSSE) + state.addDirectFloatArg(); + else + state.addDirectIntArg(); + } + return CABIParamInfo(abiTypes, ParmDirect, attr, sigOff); + } else { + state.addIndirectArg(); + llvm::Type *ptrTyp = llvm::PointerType::get(ptyp, 0); + return CABIParamInfo(ptrTyp, ParmIndirect, AttrByVal, sigOff); + } +} + +CABIParamInfo CABIOracleRISC_V::analyzeABIReturn(Btype *resultType, + ABIState &state) { + llvm::Type *rtyp = resultType->type(); + CABIParamDisp rdisp = + (rtyp == tm_->llvmVoidType() ? ParmIgnore : classifyArgType(resultType)); + + if (rdisp == ParmIgnore) { + // This corresponds to a function with no returns or + // returning an empty composite. + llvm::Type *voidType = tm_->llvmVoidType(); + return CABIParamInfo(voidType, ParmIgnore, AttrNone, -1); + } + + if (rdisp == ParmIndirect) { + // Return value will be passed in memory, via a hidden + // struct return param. + // It is on stack, therefore address space 0. + llvm::Type *ptrTyp = llvm::PointerType::get(rtyp, 0); + state.addIndirectReturn(); + return CABIParamInfo(ptrTyp, ParmIndirect, AttrStructReturn, 0); + } + + // Figure out what to do in the direct case + assert(rdisp == ParmDirect); + EightByteInfo ebi(resultType, tm_); + auto ®ions = ebi.regions(); + if (regions.size() == 1) { + // Single value + return CABIParamInfo(regions[0].abiDirectType, ParmDirect, regions[0].attr, + -1); + } + + // Two-element struct + assert(regions.size() == 2); + llvm::Type *abiTyp = tm_->makeLLVMTwoElementStructType( + regions[0].abiDirectType, regions[1].abiDirectType); + return CABIParamInfo(abiTyp, ParmDirect, AttrNone, -1); +} diff --git a/bridge/go-llvm-cabi-oracle.h b/bridge/go-llvm-cabi-oracle.h index 86b79f5..67097a1 100644 --- a/bridge/go-llvm-cabi-oracle.h +++ b/bridge/go-llvm-cabi-oracle.h @@ -248,4 +248,18 @@ class CABIOracleARM_AAPCS : public CABIOracleArgumentAnalyzer { bool canPassDirectly(unsigned regsInt, unsigned regsSSE, ABIState &state); }; +class CABIOracleRISC_V : public CABIOracleArgumentAnalyzer { +public: + // Given information on the param types and result type for a + // function, create an oracle object that can answer C ABI + // queries about the function. + CABIOracleRISC_V(TypeManager *typeManager); + CABIParamInfo analyzeABIParam(Btype *pType, ABIState &state); + CABIParamInfo analyzeABIReturn(Btype *resultType, ABIState &state); + +private: + CABIParamDisp classifyArgType(Btype *btype); + bool canPassDirectly(unsigned regsInt, unsigned regsSSE, ABIState &state); +}; + #endif // LLVMGOFRONTEND_GO_LLVM_CABI_ORACLE_H diff --git a/cmake/modules/AutoGenGo.cmake b/cmake/modules/AutoGenGo.cmake index a0a3af6..22f2376 100644 --- a/cmake/modules/AutoGenGo.cmake +++ b/cmake/modules/AutoGenGo.cmake @@ -375,11 +375,8 @@ function(mkzdefaultcc package outfile ccpath cxxpath) CMAKE_PARSE_ARGUMENTS(ARG "EXPORT" "" "" ${ARGN}) # Construct default driver path - if (GOLLVM_DRIVER_DIR) - set(driverpath "${GOLLVM_DRIVER_DIR}/bin/llvm-goc") - else() - set(driverpath "${GOLLVM_INSTALL_DIR}/bin/llvm-goc") - endif() + set(driverpath "${GOLLVM_INSTALL_DIR}/bin/llvm-goc") + file(REMOVE ${outfile}) file(WRITE ${outfile} "package ${package}\n\n") diff --git a/cmake/modules/GoVars.cmake b/cmake/modules/GoVars.cmake index 5aa2c32..c8d0e98 100644 --- a/cmake/modules/GoVars.cmake +++ b/cmake/modules/GoVars.cmake @@ -11,6 +11,10 @@ if( ${llarch} STREQUAL "x86_64" ) # LLVM's "aarch64" is the same as Go's "arm64". elseif( ${llarch} STREQUAL "aarch64" ) set(goarch "arm64") +elseif( ${llarch} STREQUAL "riscv64" ) + # Driver::installedLibDir honors ./lib64 only + # Future change needed (along with those in AddGollvm.cmake) + set(goarch "riscv64") else() message(SEND_ERROR "Arch ${llarch} not yet supported") endif() @@ -27,6 +31,10 @@ elseif( ${llarch} STREQUAL "aarch64" ) # Driver::installedLibDir honors ./lib64 only # Future change needed (along with those in AddGollvm.cmake) set(library_suffix "64") +elseif( ${llarch} STREQUAL "riscv64" ) + # Driver::installedLibDir honors ./lib64 only + # Future change needed (along with those in AddGollvm.cmake) + set(library_suffix "64") else() message(SEND_ERROR "Arch ${llarch} not yet supported") endif() diff --git a/cmake/modules/LibbacktraceUtils.cmake b/cmake/modules/LibbacktraceUtils.cmake index dc54f18..2c018fd 100644 --- a/cmake/modules/LibbacktraceUtils.cmake +++ b/cmake/modules/LibbacktraceUtils.cmake @@ -11,6 +11,9 @@ function(setup_libbacktrace) elseif( ${goarch} STREQUAL "arm64") set(BACKTRACE_ELF_SIZE 64) set(HAVE_GETIPINFO 1) + elseif( ${goarch} STREQUAL "riscv64") + set(BACKTRACE_ELF_SIZE 64) + set(HAVE_GETIPINFO 1) else() message(SEND_ERROR "Libbacktrace config setup not implemented for ${goarch}") endif() @@ -68,6 +71,10 @@ function(setup_libbacktrace) if(GOLLVM_USE_SPLIT_STACK) string(APPEND libbacktraceflags " -fsplit-stack ${CFPROTECTION_WORKAROUND}") endif() + # Force -funwind-tables to be used for RISC-V so .eh_frame exists for stack unwinding. + if (${goarch} STREQUAL "riscv64") + string(APPEND libbacktraceflags " -funwind-tables") + endif() string(APPEND libbacktraceflags " ${GOLLVM_EXTRA_CFLAGS}") # Object libraries built from libbacktrace sources. diff --git a/cmake/modules/LibffiUtils.cmake b/cmake/modules/LibffiUtils.cmake index 035b647..a05bbe9 100644 --- a/cmake/modules/LibffiUtils.cmake +++ b/cmake/modules/LibffiUtils.cmake @@ -9,6 +9,8 @@ function(setup_libffi libffi_srcroot) set(arch_dir "aarch64") elseif(${llarch} STREQUAL "x86_64") set(arch_dir "x86") + elseif(${llarch} STREQUAL "riscv64") + set(arch_dir "riscv") else() message(SEND_ERROR "Arch ${llarch} not yet supported") endif() @@ -35,7 +37,7 @@ function(setup_libffi libffi_srcroot) set(HAVE_64BIT 0) else() set(HAVE_64BIT 1) - if(NOT ${llarch} STREQUAL "aarch64") + if(${llarch} STREQUAL "x86_64") set(HAVE_AS_X86_64_UNWIND_SECTION_TYPE 1) endif() endif() @@ -62,6 +64,8 @@ function(setup_libffi libffi_srcroot) # Set target based on arch. if(HAVE_64BIT AND ${llarch} STREQUAL "aarch64") set(TARGET AARCH64) + elseif(HAVE_64BIT AND ${llarch} STREQUAL "riscv64") + set(TARGET RISCV64) elseif(HAVE_64BIT) set(TARGET X86_64) else() @@ -86,6 +90,10 @@ function(setup_libffi libffi_srcroot) if(GOLLVM_USE_SPLIT_STACK) string(APPEND libffiflags " -fsplit-stack ${CFPROTECTION_WORKAROUND}") endif() + # Force -funwind-tables to be used for RISC-V so .eh_frame exists for stack unwinding. + if (${goarch} STREQUAL "riscv64") + string(APPEND libffiflags " -funwind-tables") + endif() string(APPEND libffiflags " ${GOLLVM_EXTRA_CFLAGS}") # Copy correct version of ffitarget.h to libgo binary root. diff --git a/driver/ArchCpusAttrs.h b/driver/ArchCpusAttrs.h index b083dda..424544a 100644 --- a/driver/ArchCpusAttrs.h +++ b/driver/ArchCpusAttrs.h @@ -4,7 +4,7 @@ // // in combination with clang: // -// clang version 11.0.0 (https://github.com/llvm/llvm-project.git 0160ad802e899c2922bc9b29564080c22eb0908c) +// clang version 15.0.0 (git@github.com:plctlab/llvm-project.git ed6894730b4329183dc2fe2c00b6c5b4aa6ed56b) // typedef struct { @@ -21,54 +21,61 @@ typedef struct { static const CpuAttrs attrs0[] = { // first entry is default cpu { "x86-64", "+cx8,+fxsr,+mmx,+sse,+sse2,+x87"}, + { "alderlake", "+adx,+aes,+avx,+avx2,+avxvnni,+bmi,+bmi2,+cldemote,+clflushopt,+clwb,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+gfni,+hreset,+invpcid,+kl,+lzcnt,+mmx,+movbe,+movdir64b,+movdiri,+pclmul,+pconfig,+pku,+popcnt,+prfchw,+ptwrite,+rdpid,+rdrnd,+rdseed,+sahf,+serialize,+sgx,+sha,+shstk,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+vaes,+vpclmulqdq,+waitpkg,+widekl,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, { "amdfam10", "+3dnow,+3dnowa,+cx16,+cx8,+fxsr,+lzcnt,+mmx,+popcnt,+prfchw,+sahf,+sse,+sse2,+sse3,+sse4a,+x87"}, { "athlon-fx", "+3dnow,+3dnowa,+cx8,+fxsr,+mmx,+sse,+sse2,+x87"}, { "athlon64", "+3dnow,+3dnowa,+cx8,+fxsr,+mmx,+sse,+sse2,+x87"}, { "athlon64-sse3", "+3dnow,+3dnowa,+cx8,+fxsr,+mmx,+sse,+sse2,+sse3,+x87"}, { "atom", "+cx16,+cx8,+fxsr,+mmx,+movbe,+sahf,+sse,+sse2,+sse3,+ssse3,+x87"}, { "barcelona", "+3dnow,+3dnowa,+cx16,+cx8,+fxsr,+lzcnt,+mmx,+popcnt,+prfchw,+sahf,+sse,+sse2,+sse3,+sse4a,+x87"}, - { "bdver1", "+aes,+avx,+cx16,+cx8,+fma4,+fxsr,+lwp,+lzcnt,+mmx,+pclmul,+popcnt,+prfchw,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+x87,+xop,+xsave"}, - { "bdver2", "+aes,+avx,+bmi,+cx16,+cx8,+f16c,+fma,+fma4,+fxsr,+lwp,+lzcnt,+mmx,+pclmul,+popcnt,+prfchw,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+tbm,+x87,+xop,+xsave"}, - { "bdver3", "+aes,+avx,+bmi,+cx16,+cx8,+f16c,+fma,+fma4,+fsgsbase,+fxsr,+lwp,+lzcnt,+mmx,+pclmul,+popcnt,+prfchw,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+tbm,+x87,+xop,+xsave,+xsaveopt"}, - { "bdver4", "+aes,+avx,+avx2,+bmi,+bmi2,+cx16,+cx8,+f16c,+fma,+fma4,+fsgsbase,+fxsr,+lwp,+lzcnt,+mmx,+movbe,+mwaitx,+pclmul,+popcnt,+prfchw,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+tbm,+x87,+xop,+xsave,+xsaveopt"}, + { "bdver1", "+aes,+avx,+crc32,+cx16,+cx8,+fma4,+fxsr,+lwp,+lzcnt,+mmx,+pclmul,+popcnt,+prfchw,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+x87,+xop,+xsave"}, + { "bdver2", "+aes,+avx,+bmi,+crc32,+cx16,+cx8,+f16c,+fma,+fma4,+fxsr,+lwp,+lzcnt,+mmx,+pclmul,+popcnt,+prfchw,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+tbm,+x87,+xop,+xsave"}, + { "bdver3", "+aes,+avx,+bmi,+crc32,+cx16,+cx8,+f16c,+fma,+fma4,+fsgsbase,+fxsr,+lwp,+lzcnt,+mmx,+pclmul,+popcnt,+prfchw,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+tbm,+x87,+xop,+xsave,+xsaveopt"}, + { "bdver4", "+aes,+avx,+avx2,+bmi,+bmi2,+crc32,+cx16,+cx8,+f16c,+fma,+fma4,+fsgsbase,+fxsr,+lwp,+lzcnt,+mmx,+movbe,+mwaitx,+pclmul,+popcnt,+prfchw,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+tbm,+x87,+xop,+xsave,+xsaveopt"}, { "bonnell", "+cx16,+cx8,+fxsr,+mmx,+movbe,+sahf,+sse,+sse2,+sse3,+ssse3,+x87"}, - { "broadwell", "+adx,+avx,+avx2,+bmi,+bmi2,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"}, + { "broadwell", "+adx,+avx,+avx2,+bmi,+bmi2,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"}, { "btver1", "+cx16,+cx8,+fxsr,+lzcnt,+mmx,+popcnt,+prfchw,+sahf,+sse,+sse2,+sse3,+sse4a,+ssse3,+x87"}, - { "btver2", "+aes,+avx,+bmi,+cx16,+cx8,+f16c,+fxsr,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+x87,+xsave,+xsaveopt"}, - { "cannonlake", "+adx,+aes,+avx,+avx2,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512ifma,+avx512vbmi,+avx512vl,+bmi,+bmi2,+clflushopt,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+pku,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sgx,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, - { "cascadelake", "+adx,+aes,+avx,+avx2,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512vl,+avx512vnni,+bmi,+bmi2,+clflushopt,+clwb,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+pku,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, - { "cooperlake", "+adx,+aes,+avx,+avx2,+avx512bf16,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512vl,+avx512vnni,+bmi,+bmi2,+clflushopt,+clwb,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+pku,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, - { "core-avx-i", "+avx,+cx16,+cx8,+f16c,+fsgsbase,+fxsr,+mmx,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"}, - { "core-avx2", "+avx,+avx2,+bmi,+bmi2,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"}, + { "btver2", "+aes,+avx,+bmi,+crc32,+cx16,+cx8,+f16c,+fxsr,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+x87,+xsave,+xsaveopt"}, + { "cannonlake", "+adx,+aes,+avx,+avx2,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512ifma,+avx512vbmi,+avx512vl,+bmi,+bmi2,+clflushopt,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+pku,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sgx,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, + { "cascadelake", "+adx,+aes,+avx,+avx2,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512vl,+avx512vnni,+bmi,+bmi2,+clflushopt,+clwb,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+pku,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, + { "cooperlake", "+adx,+aes,+avx,+avx2,+avx512bf16,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512vl,+avx512vnni,+bmi,+bmi2,+clflushopt,+clwb,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+pku,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, + { "core-avx-i", "+avx,+crc32,+cx16,+cx8,+f16c,+fsgsbase,+fxsr,+mmx,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"}, + { "core-avx2", "+avx,+avx2,+bmi,+bmi2,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"}, { "core2", "+cx16,+cx8,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+ssse3,+x87"}, - { "corei7", "+cx16,+cx8,+fxsr,+mmx,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87"}, - { "corei7-avx", "+avx,+cx16,+cx8,+fxsr,+mmx,+pclmul,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"}, - { "goldmont", "+aes,+clflushopt,+cx16,+cx8,+fsgsbase,+fxsr,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, - { "goldmont-plus", "+aes,+clflushopt,+cx16,+cx8,+fsgsbase,+fxsr,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+ptwrite,+rdpid,+rdrnd,+rdseed,+sahf,+sgx,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, - { "haswell", "+avx,+avx2,+bmi,+bmi2,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"}, - { "icelake-client", "+adx,+aes,+avx,+avx2,+avx512bitalg,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512ifma,+avx512vbmi,+avx512vbmi2,+avx512vl,+avx512vnni,+avx512vpopcntdq,+bmi,+bmi2,+clflushopt,+clwb,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+gfni,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+pku,+popcnt,+prfchw,+rdpid,+rdrnd,+rdseed,+sahf,+sgx,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+vaes,+vpclmulqdq,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, - { "icelake-server", "+adx,+aes,+avx,+avx2,+avx512bitalg,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512ifma,+avx512vbmi,+avx512vbmi2,+avx512vl,+avx512vnni,+avx512vpopcntdq,+bmi,+bmi2,+clflushopt,+clwb,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+gfni,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+pconfig,+pku,+popcnt,+prfchw,+rdpid,+rdrnd,+rdseed,+sahf,+sgx,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+vaes,+vpclmulqdq,+wbnoinvd,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, - { "ivybridge", "+avx,+cx16,+cx8,+f16c,+fsgsbase,+fxsr,+mmx,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"}, + { "corei7", "+crc32,+cx16,+cx8,+fxsr,+mmx,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87"}, + { "corei7-avx", "+avx,+crc32,+cx16,+cx8,+fxsr,+mmx,+pclmul,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"}, + { "goldmont", "+aes,+clflushopt,+crc32,+cx16,+cx8,+fsgsbase,+fxsr,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, + { "goldmont-plus", "+aes,+clflushopt,+crc32,+cx16,+cx8,+fsgsbase,+fxsr,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+ptwrite,+rdpid,+rdrnd,+rdseed,+sahf,+sgx,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, + { "haswell", "+avx,+avx2,+bmi,+bmi2,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"}, + { "icelake-client", "+adx,+aes,+avx,+avx2,+avx512bitalg,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512ifma,+avx512vbmi,+avx512vbmi2,+avx512vl,+avx512vnni,+avx512vpopcntdq,+bmi,+bmi2,+clflushopt,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+gfni,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+pku,+popcnt,+prfchw,+rdpid,+rdrnd,+rdseed,+sahf,+sgx,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+vaes,+vpclmulqdq,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, + { "icelake-server", "+adx,+aes,+avx,+avx2,+avx512bitalg,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512ifma,+avx512vbmi,+avx512vbmi2,+avx512vl,+avx512vnni,+avx512vpopcntdq,+bmi,+bmi2,+clflushopt,+clwb,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+gfni,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+pconfig,+pku,+popcnt,+prfchw,+rdpid,+rdrnd,+rdseed,+sahf,+sgx,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+vaes,+vpclmulqdq,+wbnoinvd,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, + { "ivybridge", "+avx,+crc32,+cx16,+cx8,+f16c,+fsgsbase,+fxsr,+mmx,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"}, { "k8", "+3dnow,+3dnowa,+cx8,+fxsr,+mmx,+sse,+sse2,+x87"}, { "k8-sse3", "+3dnow,+3dnowa,+cx8,+fxsr,+mmx,+sse,+sse2,+sse3,+x87"}, - { "knl", "+adx,+aes,+avx,+avx2,+avx512cd,+avx512er,+avx512f,+avx512pf,+bmi,+bmi2,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+prefetchwt1,+prfchw,+rdrnd,+rdseed,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"}, - { "knm", "+adx,+aes,+avx,+avx2,+avx512cd,+avx512er,+avx512f,+avx512pf,+avx512vpopcntdq,+bmi,+bmi2,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+prefetchwt1,+prfchw,+rdrnd,+rdseed,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"}, - { "nehalem", "+cx16,+cx8,+fxsr,+mmx,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87"}, + { "knl", "+adx,+aes,+avx,+avx2,+avx512cd,+avx512er,+avx512f,+avx512pf,+bmi,+bmi2,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+prefetchwt1,+prfchw,+rdrnd,+rdseed,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"}, + { "knm", "+adx,+aes,+avx,+avx2,+avx512cd,+avx512er,+avx512f,+avx512pf,+avx512vpopcntdq,+bmi,+bmi2,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+prefetchwt1,+prfchw,+rdrnd,+rdseed,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"}, + { "nehalem", "+crc32,+cx16,+cx8,+fxsr,+mmx,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87"}, { "nocona", "+cx16,+cx8,+fxsr,+mmx,+sse,+sse2,+sse3,+x87"}, { "opteron", "+3dnow,+3dnowa,+cx8,+fxsr,+mmx,+sse,+sse2,+x87"}, { "opteron-sse3", "+3dnow,+3dnowa,+cx8,+fxsr,+mmx,+sse,+sse2,+sse3,+x87"}, { "penryn", "+cx16,+cx8,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87"}, - { "sandybridge", "+avx,+cx16,+cx8,+fxsr,+mmx,+pclmul,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"}, - { "silvermont", "+cx16,+cx8,+fxsr,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87"}, - { "skx", "+adx,+aes,+avx,+avx2,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512vl,+bmi,+bmi2,+clflushopt,+clwb,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+pku,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, - { "skylake", "+adx,+aes,+avx,+avx2,+bmi,+bmi2,+clflushopt,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sgx,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, - { "skylake-avx512", "+adx,+aes,+avx,+avx2,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512vl,+bmi,+bmi2,+clflushopt,+clwb,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+pku,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, - { "slm", "+cx16,+cx8,+fxsr,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87"}, - { "tigerlake", "+adx,+aes,+avx,+avx2,+avx512bitalg,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512ifma,+avx512vbmi,+avx512vbmi2,+avx512vl,+avx512vnni,+avx512vp2intersect,+avx512vpopcntdq,+bmi,+bmi2,+clflushopt,+clwb,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+gfni,+invpcid,+lzcnt,+mmx,+movbe,+movdir64b,+movdiri,+pclmul,+pku,+popcnt,+prfchw,+rdpid,+rdrnd,+rdseed,+sahf,+sgx,+sha,+shstk,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+vaes,+vpclmulqdq,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, - { "tremont", "+aes,+clflushopt,+clwb,+cx16,+cx8,+fsgsbase,+fxsr,+gfni,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+ptwrite,+rdpid,+rdrnd,+rdseed,+sahf,+sgx,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, - { "westmere", "+cx16,+cx8,+fxsr,+mmx,+pclmul,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87"}, - { "znver1", "+adx,+aes,+avx,+avx2,+bmi,+bmi2,+clflushopt,+clzero,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+lzcnt,+mmx,+movbe,+mwaitx,+pclmul,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, - { "znver2", "+adx,+aes,+avx,+avx2,+bmi,+bmi2,+clflushopt,+clwb,+clzero,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+lzcnt,+mmx,+movbe,+mwaitx,+pclmul,+popcnt,+prfchw,+rdpid,+rdrnd,+rdseed,+sahf,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+wbnoinvd,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, + { "rocketlake", "+adx,+aes,+avx,+avx2,+avx512bitalg,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512ifma,+avx512vbmi,+avx512vbmi2,+avx512vl,+avx512vnni,+avx512vpopcntdq,+bmi,+bmi2,+clflushopt,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+gfni,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+pku,+popcnt,+prfchw,+rdpid,+rdrnd,+rdseed,+sahf,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+vaes,+vpclmulqdq,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, + { "sandybridge", "+avx,+crc32,+cx16,+cx8,+fxsr,+mmx,+pclmul,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"}, + { "sapphirerapids", "+adx,+aes,+amx-bf16,+amx-int8,+amx-tile,+avx,+avx2,+avx512bf16,+avx512bitalg,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512fp16,+avx512ifma,+avx512vbmi,+avx512vbmi2,+avx512vl,+avx512vnni,+avx512vp2intersect,+avx512vpopcntdq,+avxvnni,+bmi,+bmi2,+cldemote,+clflushopt,+clwb,+crc32,+cx16,+cx8,+enqcmd,+f16c,+fma,+fsgsbase,+fxsr,+gfni,+invpcid,+lzcnt,+mmx,+movbe,+movdir64b,+movdiri,+pclmul,+pconfig,+pku,+popcnt,+prfchw,+ptwrite,+rdpid,+rdrnd,+rdseed,+sahf,+serialize,+sgx,+sha,+shstk,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+tsxldtrk,+uintr,+vaes,+vpclmulqdq,+waitpkg,+wbnoinvd,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, + { "silvermont", "+crc32,+cx16,+cx8,+fxsr,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87"}, + { "skx", "+adx,+aes,+avx,+avx2,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512vl,+bmi,+bmi2,+clflushopt,+clwb,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+pku,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, + { "skylake", "+adx,+aes,+avx,+avx2,+bmi,+bmi2,+clflushopt,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sgx,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, + { "skylake-avx512", "+adx,+aes,+avx,+avx2,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512vl,+bmi,+bmi2,+clflushopt,+clwb,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+pku,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, + { "slm", "+crc32,+cx16,+cx8,+fxsr,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87"}, + { "tigerlake", "+adx,+aes,+avx,+avx2,+avx512bitalg,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512ifma,+avx512vbmi,+avx512vbmi2,+avx512vl,+avx512vnni,+avx512vp2intersect,+avx512vpopcntdq,+bmi,+bmi2,+clflushopt,+clwb,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+gfni,+invpcid,+kl,+lzcnt,+mmx,+movbe,+movdir64b,+movdiri,+pclmul,+pku,+popcnt,+prfchw,+rdpid,+rdrnd,+rdseed,+sahf,+sgx,+sha,+shstk,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+vaes,+vpclmulqdq,+widekl,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, + { "tremont", "+aes,+clflushopt,+clwb,+crc32,+cx16,+cx8,+fsgsbase,+fxsr,+gfni,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+ptwrite,+rdpid,+rdrnd,+rdseed,+sahf,+sgx,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, + { "westmere", "+crc32,+cx16,+cx8,+fxsr,+mmx,+pclmul,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87"}, + { "x86-64-v2", "+crc32,+cx16,+cx8,+fxsr,+mmx,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87"}, + { "x86-64-v3", "+avx,+avx2,+bmi,+bmi2,+crc32,+cx16,+cx8,+f16c,+fma,+fxsr,+lzcnt,+mmx,+movbe,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave"}, + { "x86-64-v4", "+avx,+avx2,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512vl,+bmi,+bmi2,+crc32,+cx16,+cx8,+f16c,+fma,+fxsr,+lzcnt,+mmx,+movbe,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave"}, + { "znver1", "+adx,+aes,+avx,+avx2,+bmi,+bmi2,+clflushopt,+clzero,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+lzcnt,+mmx,+movbe,+mwaitx,+pclmul,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, + { "znver2", "+adx,+aes,+avx,+avx2,+bmi,+bmi2,+clflushopt,+clwb,+clzero,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+lzcnt,+mmx,+movbe,+mwaitx,+pclmul,+popcnt,+prfchw,+rdpid,+rdrnd,+rdseed,+sahf,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+wbnoinvd,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, + { "znver3", "+adx,+aes,+avx,+avx2,+bmi,+bmi2,+clflushopt,+clwb,+clzero,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+mwaitx,+pclmul,+pku,+popcnt,+prfchw,+rdpid,+rdrnd,+rdseed,+sahf,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+vaes,+vpclmulqdq,+wbnoinvd,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, { "", "" } // sentinel }; @@ -77,52 +84,80 @@ static const CpuAttrs attrs1[] = { // first entry is default cpu { "generic", "+neon"}, { "a64fx", "+aes,+crc,+crypto,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rdm,+sha2,+sve,+v8.2a"}, - { "apple-a10", "+aes,+crc,+crypto,+fp-armv8,+neon,+rdm,+sha2,+zcm,+zcz"}, - { "apple-a11", "+aes,+crc,+crypto,+fp-armv8,+lse,+neon,+ras,+rdm,+sha2,+v8.2a,+zcm,+zcz"}, + { "apple-a10", "+aes,+crc,+crypto,+fp-armv8,+neon,+rdm,+sha2,+v8a,+zcm,+zcz"}, + { "apple-a11", "+aes,+crc,+crypto,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rdm,+sha2,+v8.2a,+zcm,+zcz"}, { "apple-a12", "+aes,+crc,+crypto,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.3a,+zcm,+zcz"}, { "apple-a13", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+sha3,+sm4,+v8.4a,+zcm,+zcz"}, - { "apple-a7", "+aes,+crypto,+fp-armv8,+neon,+sha2,+zcm,+zcz"}, - { "apple-a8", "+aes,+crypto,+fp-armv8,+neon,+sha2,+zcm,+zcz"}, - { "apple-a9", "+aes,+crypto,+fp-armv8,+neon,+sha2,+zcm,+zcz"}, + { "apple-a14", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.5a,+zcm,+zcz"}, + { "apple-a7", "+aes,+crypto,+fp-armv8,+neon,+sha2,+v8a,+zcm,+zcz"}, + { "apple-a8", "+aes,+crypto,+fp-armv8,+neon,+sha2,+v8a,+zcm,+zcz"}, + { "apple-a9", "+aes,+crypto,+fp-armv8,+neon,+sha2,+v8a,+zcm,+zcz"}, + { "apple-m1", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.5a,+zcm,+zcz"}, { "apple-s4", "+aes,+crc,+crypto,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.3a,+zcm,+zcz"}, { "apple-s5", "+aes,+crc,+crypto,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.3a,+zcm,+zcz"}, { "carmel", "+aes,+crc,+crypto,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rdm,+sha2,+v8.2a"}, - { "cortex-a34", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2"}, - { "cortex-a35", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2"}, - { "cortex-a53", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2"}, + { "cortex-a34", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2,+v8a"}, + { "cortex-a35", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2,+v8a"}, + { "cortex-a510", "+crc,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+lse,+neon,+pauth,+ras,+rcpc,+rdm,+sve,+sve2,+sve2-bitperm,+v9a"}, + { "cortex-a53", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2,+v8a"}, { "cortex-a55", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.2a"}, - { "cortex-a57", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2"}, + { "cortex-a57", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2,+v8a"}, { "cortex-a65", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.2a"}, { "cortex-a65ae", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.2a"}, - { "cortex-a72", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2"}, - { "cortex-a73", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2"}, + { "cortex-a710", "+crc,+dotprod,+flagm,+fp-armv8,+fp16fml,+fullfp16,+lse,+neon,+pauth,+ras,+rcpc,+rdm,+sve,+sve2,+sve2-bitperm,+v9a"}, + { "cortex-a72", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2,+v8a"}, + { "cortex-a73", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2,+v8a"}, { "cortex-a75", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.2a"}, { "cortex-a76", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.2a"}, { "cortex-a76ae", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.2a"}, { "cortex-a77", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.2a"}, { "cortex-a78", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.2a"}, + { "cortex-a78c", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.2a"}, + { "cortex-r82", "+crc,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+v8r"}, { "cortex-x1", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.2a"}, - { "cyclone", "+aes,+crypto,+fp-armv8,+neon,+sha2,+zcm,+zcz"}, - { "exynos-m3", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2"}, + { "cortex-x1c", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+pauth,+ras,+rcpc,+rdm,+sha2,+v8.2a"}, + { "cortex-x2", "+crc,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+lse,+neon,+pauth,+ras,+rcpc,+rdm,+sve,+sve2,+sve2-bitperm,+v9a"}, + { "cyclone", "+aes,+crypto,+fp-armv8,+neon,+sha2,+v8a,+zcm,+zcz"}, + { "exynos-m3", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2,+v8a"}, { "exynos-m4", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rdm,+sha2,+v8.2a"}, { "exynos-m5", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rdm,+sha2,+v8.2a"}, - { "falkor", "+aes,+crc,+crypto,+fp-armv8,+neon,+rdm,+sha2"}, - { "kryo", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2"}, + { "falkor", "+aes,+crc,+crypto,+fp-armv8,+neon,+rdm,+sha2,+v8a"}, + { "kryo", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2,+v8a"}, + { "neoverse-512tvb", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+sha3,+sm4,+sve,+v8.4a"}, { "neoverse-e1", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.2a"}, { "neoverse-n1", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+spe,+v8.2a"}, + { "neoverse-n2", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+sve,+sve2,+sve2-bitperm,+v8.5a"}, + { "neoverse-v1", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+sha3,+sm4,+sve,+v8.4a"}, { "saphira", "+aes,+crc,+crypto,+fp-armv8,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+spe,+v8.3a"}, - { "thunderx", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2,+spe"}, + { "thunderx", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2,+spe,+v8a"}, { "thunderx2t99", "+aes,+crc,+crypto,+fp-armv8,+lse,+neon,+rdm,+sha2,+v8.1a"}, { "thunderx3t110", "+aes,+crc,+crypto,+fp-armv8,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+spe,+v8.3a"}, - { "thunderxt81", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2,+spe"}, - { "thunderxt83", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2,+spe"}, - { "thunderxt88", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2,+spe"}, + { "thunderxt81", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2,+spe,+v8a"}, + { "thunderxt83", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2,+spe,+v8a"}, + { "thunderxt88", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2,+spe,+v8a"}, { "tsv110", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+lse,+neon,+ras,+rdm,+sha2,+spe,+v8.2a"}, { "", "" } // sentinel }; +// triple: riscv64-unknown-linux-gnu +static const CpuAttrs attrs2[] = { + // first entry is default cpu + { "", "+64bit,+a,+c,+d,+f,+m,+relax,-save-restore"}, + { "generic-rv64", "+64bit,+a,+c,+d,+f,+m,+relax,-save-restore"}, + { "rocket-rv64", "+64bit,+a,+c,+d,+f,+m,+relax,-save-restore"}, + { "sifive-7-rv64", "+64bit,+a,+c,+d,+f,+m,+relax,-save-restore"}, + { "sifive-s21", "+64bit,+a,+c,+m,+relax,-save-restore"}, + { "sifive-s51", "+64bit,+a,+c,+m,+relax,-save-restore"}, + { "sifive-s54", "+64bit,+a,+c,+d,+f,+m,+relax,-save-restore"}, + { "sifive-s76", "+64bit,+a,+c,+d,+f,+m,+relax,-save-restore"}, + { "sifive-u54", "+64bit,+a,+c,+d,+f,+m,+relax,-save-restore"}, + { "sifive-u74", "+64bit,+a,+c,+d,+f,+m,+relax,-save-restore"}, + { "", "" } // sentinel +}; + const TripleCpus triples[] = { { "x86_64-unknown-linux-gnu", &attrs0[0] }, { "aarch64-unknown-linux-gnu", &attrs1[0] }, + { "riscv64-unknown-linux-gnu", &attrs2[0] }, { "", nullptr } // sentinel }; diff --git a/driver/CompileGo.cpp b/driver/CompileGo.cpp index 3312a7a..48301da 100644 --- a/driver/CompileGo.cpp +++ b/driver/CompileGo.cpp @@ -413,6 +413,9 @@ bool CompileGoImpl::setup(const Action &jobAction) TargetOptions Options; + if (triple_.getArch() == llvm::Triple::riscv64) + Options.MCOptions.ABIName = "lp64d"; + auto jat = jobAction.type(); assert(jat == Action::A_CompileAndAssemble || jat == Action::A_Compile); @@ -860,9 +863,10 @@ bool CompileGoImpl::invokeBackEnd(const Action &jobAction) createTargetTransformInfoWrapperPass(target_->getTargetIRAnalysis())); createPasses(modulePasses, functionPasses); - // Disable inlining getg in some cases on x86_64. - if (triple_.getArch() == llvm::Triple::x86_64) { - modulePasses.add(createGoSafeGetgPass()); + // Disable inlining getg in some cases on x86_64 and RISC-V. + if (triple_.getArch() == llvm::Triple::x86_64 || + triple_.getArch() == llvm::Triple::riscv64) { + modulePasses.add(createGoSafeGetgPass()); } // Add statepoint insertion pass to the end of optimization pipeline, diff --git a/driver/Driver.cpp b/driver/Driver.cpp index 777cc2b..c8a7db5 100644 --- a/driver/Driver.cpp +++ b/driver/Driver.cpp @@ -418,10 +418,6 @@ ToolChain *Driver::setup() triple_ = defaultTargetTriple; if (const opt::Arg *arg = args_.getLastArg(gollvm::options::OPT_target_EQ)) triple_ = Triple(Triple::normalize(arg->getValue())); - if (triple_ != defaultTargetTriple) { - errs() << progname_ << ": error: gollvm doesn't support cross compiling yet\n"; - return nullptr; - } // Honor -dumpmachine if (args_.hasArg(gollvm::options::OPT_dumpmachine)) { diff --git a/driver/GccUtils.cpp b/driver/GccUtils.cpp index f8f8c8e..01fc06c 100644 --- a/driver/GccUtils.cpp +++ b/driver/GccUtils.cpp @@ -190,6 +190,16 @@ bool GCCInstallationDetector::selectLibDirs(state &s) s.triple.setTriple(triple_.str()); s.suffixes = {""}; break; + case llvm::Triple::riscv64: + s.tripleAliases = { + triple_.str(), + "riscv64-linux-gnu", "riscv64-unknown-linux-gnu" + }; + s.libdirs.push_back("/lib"); + s.libdirs.push_back("/lib64"); + s.triple.setTriple(triple_.str()); + s.suffixes = {""}; + break; default: llvm::errs() << "error: unsupported triple " << triple_.str() << " in " << __FUNCTION__ << "\n"; diff --git a/driver/GnuTools.cpp b/driver/GnuTools.cpp index ea148f5..ca80bef 100644 --- a/driver/GnuTools.cpp +++ b/driver/GnuTools.cpp @@ -218,6 +218,9 @@ void Linker::addLDM(llvm::opt::ArgStringList &cmdArgs) // Currently only support linux/arm64 cmdArgs.push_back("aarch64linux"); break; + case llvm::Triple::riscv64: + cmdArgs.push_back("elf64lriscv"); + break; default: // unhandled architecture cmdArgs.push_back("%unknown%"); diff --git a/driver/IntegAssembler.cpp b/driver/IntegAssembler.cpp index a40be9f..77b42f8 100644 --- a/driver/IntegAssembler.cpp +++ b/driver/IntegAssembler.cpp @@ -179,6 +179,8 @@ bool IntegAssemblerImpl::invokeAssembler() assert(MRI && "Unable to create target register info!"); MCTargetOptions MCOptions; + if (triple_.getArch() == llvm::Triple::riscv64) + MCOptions.ABIName = "lp64d"; std::unique_ptr MAI( TheTarget->createMCAsmInfo(*MRI, Trip, MCOptions)); assert(MAI && "Unable to create target asm info!"); diff --git a/driver/LinuxToolChain.cpp b/driver/LinuxToolChain.cpp index a12b794..2c304ca 100644 --- a/driver/LinuxToolChain.cpp +++ b/driver/LinuxToolChain.cpp @@ -145,6 +145,10 @@ std::string Linux::getDynamicLinker(const llvm::opt::ArgList &args) Loader = "ld-linux-x86-64.so.2"; break; } + case llvm::Triple::riscv64: + LibDir = "lib"; + Loader = "ld-linux-riscv64-lp64d.so.1"; + break; } if (auto *Arg = args.getLastArg(gollvm::options::OPT_sysroot_EQ)) { std::string Sysroot = Arg->getValue(); diff --git a/libgo/CMakeLists.txt b/libgo/CMakeLists.txt index 6fcdff6..8585c90 100644 --- a/libgo/CMakeLists.txt +++ b/libgo/CMakeLists.txt @@ -86,6 +86,9 @@ set(tmp_libgo_extra_gocflags ${GOLLVM_EXTRA_GOCFLAGS}) if(GOLLVM_EXTRA_GOCFLAGS) string(REPLACE " " ";" libgo_extra_gocflags ${tmp_libgo_extra_gocflags}) endif() +if (${llarch} STREQUAL "riscv64") + string(APPEND libgo_extra_gocflags ";-latomic") +endif() if(NOT GOLLVM_USE_SPLIT_STACK) list(APPEND libgo_extra_gocflags "-fno-split-stack") endif() @@ -510,7 +513,7 @@ list(APPEND runtimecfiles "go/syscall/signame.c" "go/syscall/wait.c") -if (NOT ${goarch} STREQUAL "arm64") +if (${goarch} STREQUAL "amd64") list(APPEND runtimecfiles "go/golang.org/x/sys/cpu/cpu_gccgo_x86.c") endif() @@ -530,6 +533,7 @@ endforeach() # go-wrapper.c is not in gofrontend/libgo list(APPEND runtimecpaths "${GOLLVM_SOURCE_DIR}/libgo/runtime/go-wrappers.c") + # Compiler flags for C files in the runtime. set(baseopts "-g -Wno-zero-length-array ") if(GOLLVM_USE_SPLIT_STACK) @@ -538,6 +542,10 @@ endif() foreach(def ${basedefines}) string(APPEND baseopts "${def} ") endforeach() +# Force -funwind-tables to be used for RISC-V so .eh_frame exists for stack unwinding. +if (${goarch} STREQUAL "riscv64") + string(APPEND baseopts "-funwind-tables ") +endif() string(APPEND baseopts "${GOLLVM_EXTRA_CFLAGS} ") # Special flags required for aeshash.c (functions in this file are called @@ -545,6 +553,8 @@ string(APPEND baseopts "${GOLLVM_EXTRA_CFLAGS} ") # specific architectural features). if (${goarch} STREQUAL "arm64") set_source_files_properties(${libgo_csrcroot}/runtime/aeshash.c PROPERTIES COMPILE_FLAGS "-march=armv8-a+crypto") +elseif (${goarch} STREQUAL "riscv64") + set_source_files_properties(${libgo_csrcroot}/runtime/aeshash.c PROPERTIES COMPILE_FLAGS "-march=rv64gc") else() set_source_files_properties(${libgo_csrcroot}/runtime/aeshash.c PROPERTIES COMPILE_FLAGS "-maes -mssse3") endif() diff --git a/tools/capture-fcn-attributes.go b/tools/capture-fcn-attributes.go index 545d7cd..d50a827 100644 --- a/tools/capture-fcn-attributes.go +++ b/tools/capture-fcn-attributes.go @@ -87,6 +87,7 @@ void Add512(vstuff *v) { var supportedTriples []string = []string{ "x86_64-unknown-linux-gnu", "aarch64-unknown-linux-gnu", + "riscv64-unknown-linux-gnu", } var ( diff --git a/unittests/BackendCore/BackendCABIOracleTests.cpp b/unittests/BackendCore/BackendCABIOracleTests.cpp index 3f3c902..aaa9589 100644 --- a/unittests/BackendCore/BackendCABIOracleTests.cpp +++ b/unittests/BackendCore/BackendCABIOracleTests.cpp @@ -438,6 +438,190 @@ TEST(BackendCABIOracleTests, ExtendedArm64) { } } +TEST(BackendCABIOracleTests, ExtendedRV64) { + LLVMContext C; + std::unique_ptr bep( + new Llvm_backend(C, nullptr, nullptr, 0, llvm::Triple(), llvm::CallingConv::C)); + Llvm_backend *be = bep.get(); + + Btype *bi8t = be->integer_type(false, 8); + Btype *bu8t = be->integer_type(true, 8); + Btype *bu64t = be->integer_type(true, 64); + Btype *bu32t = be->integer_type(true, 32); + Btype *bi16t = be->integer_type(false, 16); + Btype *bf32t = be->float_type(32); + Btype *bf64t = be->float_type(64); + Btype *bpu64t = be->pointer_type(bu64t); + Btype *bpf64t = be->pointer_type(bf64t); + Btype *st0 = mkBackendStruct(be, nullptr); + Btype *st1 = mkBackendStruct(be, bi8t, "a", bu8t, "b", bf32t, "c", nullptr); + Btype *st2 = mkBackendStruct(be, bf64t, "f1", bf64t, "f2", nullptr); + Btype *st3 = mkBackendStruct(be, st2, "f1", bi8t, "f2", nullptr); + Btype *st4 = mkBackendStruct(be, bf32t, "f1", bf32t, "f2", nullptr); + Btype *st5 = mkBackendStruct(be, bf32t, "f1", nullptr); + Btype *st6 = mkBackendStruct(be, bf32t, "f1", bi8t, "a", bu8t, "b", + bu64t, "c", nullptr); + Btype *st7 = mkBackendStruct(be, bf32t, "f1", bu32t, "f2", nullptr); + Btype *st8 = mkBackendStruct(be, bi8t, "f1", bi16t, "f2", st7, "f3", nullptr); + Btype *stii = mkBackendStruct(be, bu64t, "a", bu64t, "b", nullptr); + Btype *stip = mkBackendStruct(be, bu64t, "a", bpu64t, "b", nullptr); + Btype *stpi = mkBackendStruct(be, bpu64t, "a", bu64t, "b", nullptr); + Btype *stpp = mkBackendStruct(be, bpu64t, "a", bpu64t, "b", nullptr); + Btype *at0 = be->array_type(bu32t, mkInt64Const(be, int64_t(0))); + Btype *at1 = be->array_type(bu32t, mkInt64Const(be, int64_t(1))); + Btype *at2 = be->array_type(bu32t, mkInt64Const(be, int64_t(3))); + Btype *at3 = be->array_type(bu8t, mkInt64Const(be, int64_t(16))); + + struct FcnItem { + FcnItem(const std::vector &r, + const std::vector &p, + const char *d, const char *t) + : results(r), parms(p), expDump(d), expTyp(t) { } + std::vector results; + std::vector parms; + const char *expDump; + const char *expTyp; + }; + + Btype *nt = nullptr; + std::vector items = { + + // 1 + FcnItem( { }, { }, + "Return: Ignore { void } sigOffset: -1 " + "Param 1: Direct AttrNest { i8* } sigOffset: 0", + "void (i8*)"), + + // 2 + FcnItem( { bi8t }, { }, + "Return: Direct AttrSext { i8 } sigOffset: -1 " + "Param 1: Direct AttrNest { i8* } sigOffset: 0", + "i8 (i8*)"), + + // 3 + FcnItem( { }, { bi8t }, + "Return: Ignore { void } sigOffset: -1 " + "Param 1: Direct AttrNest { i8* } sigOffset: 0 " + "Param 2: Direct AttrSext { i8 } sigOffset: 1", + "void (i8*, i8)"), + + // 4 + FcnItem( { }, { st5, bpf64t }, + "Return: Ignore { void } sigOffset: -1 " + "Param 1: Direct AttrNest { i8* } sigOffset: 0 " + "Param 2: Direct { float } sigOffset: 1 " + "Param 3: Direct { double* } sigOffset: 2", + "void (i8*, float, double*)"), + + // 5 + FcnItem({ bi8t, bf64t }, { bi8t, bu8t, st0 }, + "Return: Direct { { i8, double } } sigOffset: -1 " + "Param 1: Direct AttrNest { i8* } sigOffset: 0 " + "Param 2: Direct AttrSext { i8 } sigOffset: 1 " + "Param 3: Direct AttrZext { i8 } sigOffset: 2 " + "Param 4: Ignore { void } sigOffset: -1", + "{ i8, double } (i8*, i8, i8)"), + + // 6 + FcnItem({ st2 }, { st2, st0, st4, st1 }, + "Return: Direct { { double, double } } sigOffset: -1 " + "Param 1: Direct AttrNest { i8* } sigOffset: 0 " + "Param 2: Direct { double, double } sigOffset: 1 " + "Param 3: Ignore { void } sigOffset: -1 " + "Param 4: Direct { { float, float } } sigOffset: 3 " + "Param 5: Direct { i64 } sigOffset: 4 ", + "{ double, double } (i8*, double, double, { float, float }, i64)"), + + // 7 + FcnItem({ st3 }, { st3, st0, bu8t }, + "Return: Indirect AttrStructReturn { { { double, double }, i8 }* } sigOffset: 0 " + "Param 1: Direct AttrNest { i8* } sigOffset: 1 " + "Param 2: Indirect AttrByVal { { { double, double }, i8 }* } sigOffset: 2 " + "Param 3: Ignore { void } sigOffset: -1 " + "Param 4: Direct AttrZext { i8 } sigOffset: 3 ", + "void ({ { double, double }, i8 }*, i8*, " + "{ { double, double }, i8 }*, i8)"), + + // 8 + FcnItem( { st6 }, { st6, st6 }, + "Return: Direct { { i64, i64 } } sigOffset: -1 " + "Param 1: Direct AttrNest { i8* } sigOffset: 0 " + "Param 2: Direct { i64, i64 } sigOffset: 1 " + "Param 3: Direct { i64, i64 } sigOffset: 3", + "{ i64, i64 } (i8*, i64, i64, i64, i64)"), + + // 9 + FcnItem( { st8 }, { st8 }, + "Return: Direct { { i64, i32 } } sigOffset: -1 " + "Param 1: Direct AttrNest { i8* } sigOffset: 0 " + "Param 2: Direct { i64, i32 } sigOffset: 1", + "{ i64, i32 } (i8*, i64, i32)"), + + // 10 + FcnItem( { at0 }, { at1 }, + "Return: Ignore { void } sigOffset: -1 " + "Param 1: Direct AttrNest { i8* } sigOffset: 0 " + "Param 2: Direct { i32 } sigOffset: 1", + "void (i8*, i32)"), + + // 11 + FcnItem( { at2 }, { at3 }, + "Return: Direct { { i64, i32 } } sigOffset: -1 " + "Param 1: Direct AttrNest { i8* } sigOffset: 0 " + "Param 2: Direct { i64, i64 } sigOffset: 1", + "{ i64, i32 } (i8*, i64, i64)"), + + // 12 + // Make sure pointerness is preserved. + FcnItem( { stip }, { stii, stpp, stpi }, + "Return: Direct { { i64, i8* } } sigOffset: -1 " + "Param 1: Direct AttrNest { i8* } sigOffset: 0 " + "Param 2: Direct { i64, i64 } sigOffset: 1 " + "Param 3: Direct { i8*, i8* } sigOffset: 3 " + "Param 4: Direct { i8*, i64 } sigOffset: 5", + "{ i64, i8* } (i8*, i64, i64, i8*, i8*, i8*, i64)"), + }; + + unsigned count = 1; + for (auto &item : items) { + std::vector results; + std::vector params; + for (auto &r : item.results) + results.push_back(mkid(r)); + for (auto &p : item.parms) + params.push_back(mkid(p)); + Btype *rt = nullptr; + if (results.size() > 1) + rt = be->struct_type(results); + Btype *t = be->function_type(mkid(nt), params, results, rt, Location()); + BFunctionType *bft = t->castToBFunctionType(); + CABIOracle cab(bft, be->typeManager()); + + { + std::string reason; + bool equal = difftokens(item.expDump, cab.toString(), reason); + EXPECT_EQ("pass", equal ? "pass" : reason); + if (!equal) { + std::cerr << "count: " << count << "\n"; + std::cerr << "exp:\n" << item.expDump << "\n"; + std::cerr << "act:\n" << cab.toString() << "\n"; + } + } + { + std::string reason; + std::string result(repr(cab.getFunctionTypeForABI())); + bool equal = difftokens(item.expTyp, result, reason); + EXPECT_EQ("pass", equal ? "pass" : reason); + if (!equal) { + std::cerr << "count: " << count << "\n"; + std::cerr << "exp:\n" << item.expTyp << "\n"; + std::cerr << "act:\n" << result << "\n"; + } + } + count++; + } +} + TEST(BackendCABIOracleTests, RecursiveCall1Amd64) { FcnTestHarness h(gollvm::driver::CallingConvId::X86_64_SysV); Llvm_backend *be = h.be(); @@ -685,6 +869,131 @@ TEST(BackendCABIOracleTests, RecursiveCall1Arm64) { EXPECT_FALSE(broken && "Module failed to verify."); } +TEST(BackendCABIOracleTests, RecursiveCall1RV64) { + FcnTestHarness h(llvm::CallingConv::C); + Llvm_backend *be = h.be(); + + // type s1 struct { + // f1, f2 float32 + // i1, i2, i3 int16 + // } + // type s2 struct { + // k float64 + // f1, f2 float32 + // } + // type s3 struct { + // f1, s1 + // f2, s2 + // } + // type s4 struct { + // } + // func foo(x s1, y s2, z s4, sm1 uint8, sm2 int8, w s3) s2 { + // if (sm1 == 0) { + // return y + // } + // return foo(x, y, z, sm1-1, sm2, w) + // } + // + + // Create struct types + Btype *bf32t = be->float_type(32); + Btype *bf64t = be->float_type(64); + Btype *bi16t = be->integer_type(false, 16); + Btype *bi8t = be->integer_type(false, 8); + Btype *bu8t = be->integer_type(true, 8); + Btype *s1 = mkBackendStruct(be, bf32t, "f1", bf32t, "f2", + bi16t, "i1", bi16t, "i2", bi16t, "i3", nullptr); + Btype *s2 = mkBackendStruct(be, bf64t, "k", bf32t, "f1", bf32t, "f2", + nullptr); + Btype *s3 = mkBackendStruct(be, s1, "f1", s2, "f2", nullptr); + Btype *s4 = mkBackendStruct(be, nullptr); + + // Create function type + BFunctionType *befty1 = mkFuncTyp(be, + L_PARM, s1, + L_PARM, s2, + L_PARM, s4, + L_PARM, bu8t, + L_PARM, bi8t, + L_PARM, s3, + L_RES, s2, + L_END); + Bfunction *func = h.mkFunction("foo", befty1); + + // sm1 == 0 + Bvariable *p3 = func->getNthParamVar(3); + Location loc; + Bexpression *vex = be->var_expression(p3, loc); + Bexpression *c0 = be->convert_expression(bu8t, mkInt32Const(be, 0), loc); + Bexpression *eq = be->binary_expression(OPERATOR_EQEQ, vex, c0, loc); + + // call + Bexpression *fn = be->function_code_expression(func, loc); + std::vector args; + Bvariable *p0 = func->getNthParamVar(0); + args.push_back(be->var_expression(p0, loc)); + + Bvariable *p1 = func->getNthParamVar(1); + args.push_back(be->var_expression(p1, loc)); + + Bvariable *p2 = func->getNthParamVar(2); + args.push_back(be->var_expression(p2, loc)); + + Bvariable *p3x = func->getNthParamVar(3); + Bexpression *vex3 = be->var_expression(p3x, loc); + Bexpression *c1 = be->convert_expression(bu8t, mkInt32Const(be, 1), loc); + Bexpression *minus = be->binary_expression(OPERATOR_MINUS, vex3, c1, loc); + args.push_back(minus); + + Bvariable *p4 = func->getNthParamVar(4); + args.push_back(be->var_expression(p4, loc)); + + Bvariable *p5 = func->getNthParamVar(5); + args.push_back(be->var_expression(p5, loc)); + Bexpression *call = be->call_expression(func, fn, args, nullptr, h.loc()); + + // return y + std::vector rvals1; + rvals1.push_back(be->var_expression(p1, loc)); + Bstatement *rst1 = h.mkReturn(rvals1, FcnTestHarness::NoAppend); + + // return call + std::vector rvals2; + rvals2.push_back(call); + Bstatement *rst2 = h.mkReturn(rvals2, FcnTestHarness::NoAppend); + + DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT( + %p3.ld.0 = load i8, i8* %p3.addr, align 1 + %sub.0 = sub i8 %p3.ld.0, 1 + %p4.ld.0 = load i8, i8* %p4.addr, align 1 + %cast.1 = bitcast { float, float, i16, i16, i16 }* %p0.addr to { { float, float }, i48 }* + %field0.0 = getelementptr inbounds { { float, float }, i48 }, { { float, float }, i48 }* %cast.1, i32 0, i32 0 + %ld.1 = load { float, float }, { float, float }* %field0.0, align 4 + %field1.0 = getelementptr inbounds { { float, float }, i48 }, { { float, float }, i48 }* %cast.1, i32 0, i32 1 + %ld.2 = load i48, i48* %field1.0, align 8 + %cast.2 = bitcast { double, float, float }* %p1.addr to { double, { float, float } }* + %field0.1 = getelementptr inbounds { double, { float, float } }, { double, { float, float } }* %cast.2, i32 0, i32 0 + %ld.3 = load double, double* %field0.1, align 8 + %field1.1 = getelementptr inbounds { double, { float, float } }, { double, { float, float } }* %cast.2, i32 0, i32 1 + %ld.4 = load { float, float }, { float, float }* %field1.1, align 4 + %call.0 = call addrspace(0) { double, { float, float } } @foo(i8* nest undef, { float, float } %ld.1, i48 %ld.2, double %ld.3, { float, float } %ld.4, i8 zeroext %sub.0, i8 signext %p4.ld.0, { { float, float, i16, i16, i16 }, { double, float, float } }* byval({ { float, float, i16, i16, i16 }, { double, float, float } }) %p5) + %cast.3 = bitcast { double, float, float }* %sret.actual.0 to { double, { float, float } }* + store { double, { float, float } } %call.0, { double, { float, float } }* %cast.3, align 8 + %cast.4 = bitcast { double, float, float }* %sret.actual.0 to { double, { float, float } }* + %ld.5 = load { double, { float, float } }, { double, { float, float } }* %cast.4, align 8 + ret { double, { float, float } } %ld.5 + )RAW_RESULT"); + + bool isOK = h.expectStmt(rst2, exp); + EXPECT_TRUE(isOK && "Statement does not have expected contents"); + + // if statement + h.mkIf(eq, rst1, rst2); + + bool broken = h.finish(PreserveDebugInfo); + EXPECT_FALSE(broken && "Module failed to verify."); +} + TEST(BackendCABIOracleTests, PassAndReturnArraysAmd64) { FcnTestHarness h(gollvm::driver::CallingConvId::X86_64_SysV); Llvm_backend *be = h.be(); @@ -776,6 +1085,53 @@ TEST(BackendCABIOracleTests, PassAndReturnArraysArm64) { EXPECT_FALSE(broken && "Module failed to verify."); } +TEST(BackendCABIOracleTests, PassAndReturnArraysRV64) { + FcnTestHarness h(llvm::CallingConv::C); + Llvm_backend *be = h.be(); + + Btype *bf32t = be->float_type(32); + Btype *bf64t = be->float_type(64); + Btype *at2f = be->array_type(bf32t, mkInt64Const(be, int64_t(2))); + Btype *at3d = be->array_type(bf64t, mkInt64Const(be, int64_t(3))); + + // func foo(fp [2]float32) [3]float64 + BFunctionType *befty1 = mkFuncTyp(be, + L_PARM, at2f, + L_RES, at3d, + L_END); + Bfunction *func = h.mkFunction("foo", befty1); + + // foo(fp) + Location loc; + Bvariable *p0 = func->getNthParamVar(0); + Bexpression *vex = be->var_expression(p0, loc); + Bexpression *fn = be->function_code_expression(func, loc); + std::vector args; + args.push_back(vex); + Bexpression *call = be->call_expression(func, fn, args, nullptr, h.loc()); + + // return foo(fp) + std::vector rvals; + rvals.push_back(call); + h.mkReturn(rvals); + + DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT( + %cast.0 = bitcast [2 x float]* %p0.addr to { float, float }* + %ld.0 = load { float, float }, { float, float }* %cast.0, align 4 + call addrspace(0) void @foo([3 x double]* sret([3 x double]) "go_sret" %sret.actual.0, i8* nest undef, { float, float } %ld.0) + %cast.1 = bitcast [3 x double]* %sret.formal.0 to i8* + %cast.2 = bitcast [3 x double]* %sret.actual.0 to i8* + call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.1, i8* align 8 %cast.2, i64 24, i1 false) + ret void + )RAW_RESULT"); + + bool isOK = h.expectBlock(exp); + EXPECT_TRUE(isOK && "Block does not have expected contents"); + + bool broken = h.finish(PreserveDebugInfo); + EXPECT_FALSE(broken && "Module failed to verify."); +} + TEST_P(BackendCABIOracleTests, EmptyStructParamsAndReturns) { auto cc = GetParam(); FcnTestHarness h(cc); @@ -992,4 +1348,75 @@ TEST(BackendCABIOracleTests, PassAndReturnComplexArm64) { EXPECT_FALSE(broken && "Module failed to verify."); } +TEST(BackendCABIOracleTests, PassAndReturnComplexRV64) { + FcnTestHarness h(llvm::CallingConv::C); + Llvm_backend *be = h.be(); + + Btype *bc64t = be->complex_type(64); + Btype *bc128t = be->complex_type(128); + + // func foo(x complex64, y complex128) complex64 + BFunctionType *befty1 = mkFuncTyp(be, + L_PARM, bc64t, + L_PARM, bc128t, + L_RES, bc64t, + L_END); + Bfunction *func = h.mkFunction("foo", befty1); + + // z = foo(x, y) + Location loc; + Bvariable *x = func->getNthParamVar(0); + Bvariable *y = func->getNthParamVar(1); + Bexpression *xvex = be->var_expression(x, loc); + Bexpression *yvex = be->var_expression(y, loc); + Bexpression *fn1 = be->function_code_expression(func, loc); + std::vector args1 = {xvex, yvex}; + Bexpression *call1 = be->call_expression(func, fn1, args1, nullptr, h.loc()); + h.mkLocal("z", bc64t, call1); + + // Call with constant args + // foo(1+2i, 3+4i) + mpc_t mpc_val1, mpc_val2; + mpc_init2(mpc_val1, 256); + mpc_set_d_d(mpc_val1, 1.0, 2.0, GMP_RNDN); + mpc_init2(mpc_val2, 256); + mpc_set_d_d(mpc_val2, 3.0, 4.0, GMP_RNDN); + Bexpression *ccon1 = be->complex_constant_expression(bc64t, mpc_val1); + Bexpression *ccon2 = be->complex_constant_expression(bc128t, mpc_val2); + mpc_clear(mpc_val1); + mpc_clear(mpc_val2); + Bexpression *fn2 = be->function_code_expression(func, loc); + std::vector args2 = {ccon1, ccon2}; + Bexpression *call2 = be->call_expression(func, fn2, args2, nullptr, h.loc()); + + // return the call expr above + std::vector rvals = {call2}; + h.mkReturn(rvals); + + DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT( + %ld.0 = load { float, float }, { float, float }* %p0.addr, align 4 + %field0.0 = getelementptr inbounds { double, double }, { double, double }* %p1.addr, i32 0, i32 0 + %ld.1 = load double, double* %field0.0, align 8 + %field1.0 = getelementptr inbounds { double, double }, { double, double }* %p1.addr, i32 0, i32 1 + %ld.2 = load double, double* %field1.0, align 8 + %call.0 = call addrspace(0) { float, float } @foo(i8* nest undef, { float, float } %ld.0, double %ld.1, double %ld.2) + store { float, float } %call.0, { float, float }* %sret.actual.0, align 4 + %cast.3 = bitcast { float, float }* %z to i8* + %cast.4 = bitcast { float, float }* %sret.actual.0 to i8* + call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.3, i8* align 4 %cast.4, i64 8, i1 false) + %ld.3 = load { float, float }, { float, float }* @const.0, align 4 + %ld.4 = load double, double* getelementptr inbounds ({ double, double }, { double, double }* @const.1, i32 0, i32 0), align 8 + %ld.5 = load double, double* getelementptr inbounds ({ double, double }, { double, double }* @const.1, i32 0, i32 1), align 8 + %call.1 = call addrspace(0) { float, float } @foo(i8* nest undef, { float, float } %ld.3, double %ld.4, double %ld.5) + store { float, float } %call.1, { float, float }* %sret.actual.1, align 4 + %ld.6 = load { float, float }, { float, float }* %sret.actual.1, align 4 + ret { float, float } %ld.6 + )RAW_RESULT"); + + bool isOK = h.expectBlock(exp); + EXPECT_TRUE(isOK && "Block does not have expected contents"); + + bool broken = h.finish(PreserveDebugInfo); + EXPECT_FALSE(broken && "Module failed to verify."); +} } // namespace From c7d631db74be41165c625dd24fcc93611bbc954c Mon Sep 17 00:00:00 2001 From: Liao Chunyu Date: Fri, 21 Apr 2023 08:33:15 +0000 Subject: [PATCH 2/2] Revert "Upstream 2023 (#32)" This reverts commit e6bae918dd5a0b95fce7163f8e027a5255d9971c. --- CMakeLists.txt | 7 +- README.md | 55 +-- bridge/go-llvm-cabi-oracle.cpp | 231 ---------- bridge/go-llvm-cabi-oracle.h | 14 - cmake/modules/AutoGenGo.cmake | 7 +- cmake/modules/GoVars.cmake | 8 - cmake/modules/LibbacktraceUtils.cmake | 7 - cmake/modules/LibffiUtils.cmake | 10 +- driver/ArchCpusAttrs.h | 141 +++--- driver/CompileGo.cpp | 10 +- driver/Driver.cpp | 4 + driver/GccUtils.cpp | 10 - driver/GnuTools.cpp | 3 - driver/IntegAssembler.cpp | 2 - driver/LinuxToolChain.cpp | 4 - libgo/CMakeLists.txt | 12 +- tools/capture-fcn-attributes.go | 1 - .../BackendCore/BackendCABIOracleTests.cpp | 427 ------------------ 18 files changed, 71 insertions(+), 882 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b8f20d8..2561f8b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,10 +18,6 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules") set(GOLLVM_USE_SPLIT_STACK ON CACHE BOOL "use split stack by default") set(GOLLVM_DEFAULT_LINKER gold CACHE STRING "default linker for Go links") -string(REGEX REPLACE "-" " " lht_components ${LLVM_DEFAULT_TARGET_TRIPLE}) -separate_arguments(lht_components) -list(GET lht_components 0 llarch) - include(CmakeUtils) include(AddGollvm) @@ -44,6 +40,9 @@ set(EXTCC "CC=${CMAKE_C_COMPILER}" "CXX=${CMAKE_CXX_COMPILER}") set(gollvm_binroot "${CMAKE_CURRENT_BINARY_DIR}") # Set MPN path according to the target processor +string(REGEX REPLACE "-" " " lht_components ${LLVM_DEFAULT_TARGET_TRIPLE}) +separate_arguments(lht_components) +list(GET lht_components 0 llarch) if( ${llarch} STREQUAL "x86_64" ) set(MPN_PATH "x86_64 generic") diff --git a/README.md b/README.md index f2278a7..1ba6551 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,6 @@ source tree, then within the LLVM tree you check out additional git repos. * [Invoking cmake and ninja](#cmakeninja) * [Installing gollvm](#installing) * [Using an installed copy of gollvm](#using) - * [Crosscompiling gollvm](#crosscompiling) * [Information for gollvm developers](#developers) [FAQ](#FAQ) @@ -121,58 +120,6 @@ hi mom! % ``` -## Crosscompiling gollvm -You need a working version of gollvm on host system to cross compile. The following script will build and install gollvm on a cross compile system. - -``` -#!/bin/bash -set -e -mkdir -p build -cd build - -RISCV=$HOME/toolchain -SOURCE=$HOME/llvm-project/llvm -TRIPLE=riscv64-unknown-linux-gnu -INSTALL=/tmp/gollvm-install - -# host -cmake -G Ninja -S $SOURCE -B build-x86 \ - -DCMAKE_INSTALL_PREFIX=install-x86 \ - -DCMAKE_BUILD_TYPE=Debug \ - -DLLVM_USE_LINKER=bfd \ - -DGOLLVM_DEFAULT_LINKER=bfd \ - -DLLVM_TARGET_ARCH="X86-64,RISCV64" \ - -DLLVM_TARGETS_TO_BUILD="X86;RISCV" - -# crosscompile -cmake -G Ninja -S $SOURCE -B build-riscv \ - -DCMAKE_INSTALL_PREFIX=$INSTALL \ - -DCMAKE_BUILD_TYPE=Debug \ - -DLLVM_USE_LINKER=bfd \ - -DGOLLVM_DEFAULT_LINKER=bfd \ - -DCMAKE_CROSSCOMPILING=True \ - -DLLVM_TARGET_ARCH=RISCV64 \ - -DLLVM_DEFAULT_TARGET_TRIPLE=$TRIPLE \ - -DLLVM_TARGETS_TO_BUILD=RISCV \ - -DCMAKE_C_COMPILER=$RISCV/bin/$TRIPLE-gcc \ - -DCMAKE_CXX_COMPILER=$RISCV/bin/$TRIPLE-g++ \ - -DLLVM_TABLEGEN=$PWD/build-x86/bin/llvm-tblgen \ - -DGOLLVM_DRIVER_DIR=$PWD/build-x86/bin \ - -DGOLLVM_EXTRA_GOCFLAGS="--target=$TRIPLE \ - --gcc-toolchain=$RISCV/ \ - --sysroot=$RISCV/sysroot" \ - -DGOLLVM_USE_SPLIT_STACK=OFF \ - -DCMAKE_C_FLAGS=-latomic \ - -DCMAKE_CXX_FLAGS=-latomic - - -# build gollvm crosscompiler -ninja -C build-x86 llvm-goc llvm-goc-token llvm-godumpspec - -# cross compile gollvm, go tools and install -ninja -C build-riscv install-gollvm -``` - # Information for gollvm developers ## Source code structure @@ -322,7 +269,7 @@ inlining, vectorization, register allocation, etc. ## Which architectures and operating systems are supported for gollvm? -Gollvm is currently supported only for x86_64, aarch64 and riscv64 Linux. +Gollvm is currently supported only for x86_64 and aarch64 Linux. ## How does the gollvm runtime differ from the main Go runtime? diff --git a/bridge/go-llvm-cabi-oracle.cpp b/bridge/go-llvm-cabi-oracle.cpp index 7eb9925..7ba851f 100644 --- a/bridge/go-llvm-cabi-oracle.cpp +++ b/bridge/go-llvm-cabi-oracle.cpp @@ -141,7 +141,6 @@ class EightByteInfo { void incorporateScalar(Btype *bt); void determineABITypesForARM_AAPCS(); void determineABITypesForX86_64_SysV(); - void determineABITypesForRISC_V(); TypeManager *tm() const { return typeManager_; } }; @@ -161,9 +160,6 @@ EightByteInfo::EightByteInfo(Btype *bt, TypeManager *tmgr) determineABITypesForARM_AAPCS(); } break; - case gollvm::driver::CallingConvId::RISCV64_C: - determineABITypesForRISC_V(); - break; default: llvm::errs() << "unsupported gollvm::driver::CallingConvId " << static_cast(cconv) << "\n"; break; @@ -495,79 +491,6 @@ void EightByteInfo::determineABITypesForX86_64_SysV() ebrs_[0].abiDirectType = tm()->llvmDoubleType(); } -// Select the appropriate abi type for each eight-byte region within -// an EightByteInfo. Pure floating point types are mapped onto float, -// double, or <2 x float> (a vector type), integer types (or something -// that is a mix of integer and non-integer) are mapped onto the -// appropriately sized integer type. -// -// Problems arise in the code below when dealing with structures with -// constructs that inject additional padding. For example, consider -// the following struct passed by value: -// -// struct { -// f1 int8 -// f2 [0]uint64 -// f3 int8 -// } -// -// Without taking into account the over-alignment of field f3, we would -// wind up with two regions, each with type int8. This in itself is not so -// bad, but creating a struct from these two types (via ::computeABIStructType) -// would give us { int8, int8 }, in which the second field doesn't have -// the correct alignment. Work around this by checking for such situations -// and promoting the type of the first EBR to 64 bits. -// -void EightByteInfo::determineABITypesForRISC_V() { - // In the direct case, ebrs_.size() cannot be greater than 2 because - // parameters larger than 16 bytes are passed indirectly. - assert(ebrs_.size() <= 2); - unsigned intRegions = 0; - unsigned floatRegions = 0; - for (auto &ebr : ebrs_) { - if (ebr.abiDirectType != nullptr) - continue; - TypDisp regionDisp = ebr.getRegionTypDisp(); - if (regionDisp == FlavSSE) { - // Case 1: two floats -> two float structs - if (ebr.types.size() == 2) { - assert(ebr.types[0] == tm()->llvmDoubleType() || - ebr.types[0] == tm()->llvmFloatType() || - ebr.types[1] == tm()->llvmDoubleType() || - ebr.types[1] == tm()->llvmFloatType()); - ebr.abiDirectType = - tm()->makeLLVMTwoElementStructType(ebr.types[0], ebr.types[1]); - } else if (ebr.types.size() == 1) { - assert(ebr.types[0] == tm()->llvmDoubleType() || - ebr.types[0] == tm()->llvmFloatType()); - ebr.abiDirectType = ebr.types[0]; - } else { - assert(false && "this should never happen"); - } - floatRegions += 1; - } else { - unsigned nel = ebr.offsets.size(); - unsigned bytes = ebr.offsets[nel - 1] - ebr.offsets[0] + - tm()->llvmTypeSize(ebr.types[nel - 1]); - assert(bytes && bytes <= 8); - // Preserve pointerness for the use of GC. - // TODO: this assumes pointer is 8 byte, so we never pack pointer - // and other stuff together. - if (ebr.types[0]->isPointerTy()) - ebr.abiDirectType = tm()->llvmPtrType(); - else - ebr.abiDirectType = tm()->llvmArbitraryIntegerType(bytes); - intRegions += 1; - } - } - - // See the example above for more on why this is needed. - if (intRegions == 2 && ebrs_[0].abiDirectType->isIntegerTy()) - ebrs_[0].abiDirectType = tm()->llvmArbitraryIntegerType(8); - else if (floatRegions == 2 && ebrs_[0].abiDirectType == tm()->llvmFloatType()) - ebrs_[0].abiDirectType = tm()->llvmDoubleType(); -} - //...................................................................... llvm::Type *CABIParamInfo::computeABIStructType(TypeManager *tm) const @@ -633,10 +556,6 @@ class ABIState { availIntRegs_ = 8; availSIMDFPRegs_ = 8; break; - case gollvm::driver::CallingConvId::RISCV64_C: - availIntRegs_ = 8; - availFloatRegs_ = 8; - break; default: llvm::errs() << "unsupported gollvm::driver::CallingConvId " << static_cast(cconv) << "\n"; break; @@ -659,11 +578,6 @@ class ABIState { availSIMDFPRegs_ = t; argCount_ += 1; } - void addDirectFloatArg() { - if (availFloatRegs_) - availFloatRegs_ -= 1; - argCount_ += 1; - } void addIndirectArg() { argCount_ += 1; } void addIndirectReturn() { if (availIntRegs_) @@ -677,7 +591,6 @@ class ABIState { unsigned availIntRegs() const { return availIntRegs_; } unsigned availSSERegs() const { return availSSERegs_; } unsigned availSIMDFPRegs() const { return availSIMDFPRegs_; } - unsigned availFloatRegs() const { return availFloatRegs_; } void clearAvailIntRegs() { availIntRegs_ = 0; } void clearAvailSIMDFPRegs() { availSIMDFPRegs_ = 0; } @@ -685,7 +598,6 @@ class ABIState { unsigned availIntRegs_; unsigned availSSERegs_; unsigned availSIMDFPRegs_; - unsigned availFloatRegs_; unsigned argCount_; }; @@ -740,10 +652,6 @@ void CABIOracle::setCC() case gollvm::driver::CallingConvId::ARM_AAPCS: cc_ = std::unique_ptr(new CABIOracleARM_AAPCS(typeManager_)); break; - case gollvm::driver::CallingConvId::RISCV64_C: - cc_ = std::unique_ptr( - new CABIOracleRISC_V(typeManager_)); - break; default: llvm::errs() << "unsupported gollvm::driver::CallingConvId " << static_cast(ccID_) << "\n"; break; @@ -1250,142 +1158,3 @@ CABIParamInfo CABIOracleARM_AAPCS::analyzeABIReturn(Btype *resultType, } //...................................................................... - -CABIOracleRISC_V::CABIOracleRISC_V(TypeManager *typeManager) - : CABIOracleArgumentAnalyzer(typeManager) {} - -CABIParamDisp CABIOracleRISC_V::classifyArgType(Btype *btype) { - int64_t sz = tm_->typeSize(btype); - return (sz == 0 ? ParmIgnore : ((sz <= 16) ? ParmDirect : ParmIndirect)); -} - -// Given the number of registers that we think a param is going to consume, and -// a state object storing the registers used so far, canPassDirectly() makes a -// decision as to whether a given param can be passed directly in registers vs -// in memory. -// -// Note the first clause, "if (regsInt + regsSIMDFP == 1) return true". This may -// seem counter-intuitive (why no check against the state object?), but this way -// of doing things is the convention used by other front ends (e.g. clang). What -// is happening here is that for larger aggregate/array params (things that -// don't fit into a single register), we'll make the pass-through-memory -// semantics explicit in the function signature and generate the explict code to -// copy things into memory. For params that do fit into a single register, -// however, we just leave them all as by-value parameters and then assume that -// the back end will do the right thing (e.g. pass the first few in registers -// and then the remaining ones in memory). -// -// Doing things this way has performance advantages in that the middle-end -// (all of the machine-independent LLVM optimization passes) won't have -// to deal with the additional chunks of stack memory and code to copy -// things onto and off of the stack (not to mention the aliasing concerns -// when a local variable's address is taken and then passed in a function -// call). - -bool CABIOracleRISC_V::canPassDirectly(unsigned regsInt, unsigned regsFloat, - ABIState &state) { - if (regsInt + regsFloat == 1) // see comment above - return true; - if (regsInt <= state.availIntRegs() && regsFloat <= state.availFloatRegs()) - return true; - return false; -} - -CABIParamInfo CABIOracleRISC_V::analyzeABIParam(Btype *paramType, - ABIState &state) { - llvm::Type *ptyp = paramType->type(); - - // The only situations in which we should be seeing AuxT types here is - // in cases where we're analyzing the signatures of builtin functions, - // meaning that there should be no structures or arrays. - assert(paramType->flavor() != Btype::AuxT || ptyp->isVoidTy() || - !(ptyp->isStructTy() || ptyp->isArrayTy() || ptyp->isVectorTy() || - ptyp->isEmptyTy() || ptyp->isIntegerTy(8) || ptyp->isIntegerTy(16))); - - CABIParamDisp pdisp = classifyArgType(paramType); - - if (pdisp == ParmIgnore) { - // Empty struct or array - llvm::Type *voidType = tm_->llvmVoidType(); - return CABIParamInfo(voidType, ParmIgnore, AttrNone, -1); - } - - int sigOff = state.argCount(); - - if (pdisp == ParmIndirect) { - // Value will be passed in memory on stack. - // Stack is always in address space 0. - llvm::Type *ptrTyp = llvm::PointerType::get(ptyp, 0); - state.addIndirectArg(); - return CABIParamInfo(ptrTyp, ParmIndirect, AttrByVal, sigOff); - } - - // Figure out what to do in the direct case - assert(pdisp == ParmDirect); - EightByteInfo ebi(paramType, tm_); - - // Figure out how many registers it would take to pass this parm directly - unsigned regsInt = 0, regsFloat = 0; - ebi.getRegisterRequirements(®sInt, ®sFloat); - - // Make direct/indirect decision - CABIParamAttr attr = AttrNone; - if (canPassDirectly(regsInt, regsFloat, state)) { - std::vector abiTypes; - for (auto &ebr : ebi.regions()) { - abiTypes.push_back(ebr.abiDirectType); - if (ebr.attr != AttrNone) { - assert(attr == AttrNone || attr == ebr.attr); - attr = ebr.attr; - } - if (ebr.getRegionTypDisp() == FlavSSE) - state.addDirectFloatArg(); - else - state.addDirectIntArg(); - } - return CABIParamInfo(abiTypes, ParmDirect, attr, sigOff); - } else { - state.addIndirectArg(); - llvm::Type *ptrTyp = llvm::PointerType::get(ptyp, 0); - return CABIParamInfo(ptrTyp, ParmIndirect, AttrByVal, sigOff); - } -} - -CABIParamInfo CABIOracleRISC_V::analyzeABIReturn(Btype *resultType, - ABIState &state) { - llvm::Type *rtyp = resultType->type(); - CABIParamDisp rdisp = - (rtyp == tm_->llvmVoidType() ? ParmIgnore : classifyArgType(resultType)); - - if (rdisp == ParmIgnore) { - // This corresponds to a function with no returns or - // returning an empty composite. - llvm::Type *voidType = tm_->llvmVoidType(); - return CABIParamInfo(voidType, ParmIgnore, AttrNone, -1); - } - - if (rdisp == ParmIndirect) { - // Return value will be passed in memory, via a hidden - // struct return param. - // It is on stack, therefore address space 0. - llvm::Type *ptrTyp = llvm::PointerType::get(rtyp, 0); - state.addIndirectReturn(); - return CABIParamInfo(ptrTyp, ParmIndirect, AttrStructReturn, 0); - } - - // Figure out what to do in the direct case - assert(rdisp == ParmDirect); - EightByteInfo ebi(resultType, tm_); - auto ®ions = ebi.regions(); - if (regions.size() == 1) { - // Single value - return CABIParamInfo(regions[0].abiDirectType, ParmDirect, regions[0].attr, - -1); - } - - // Two-element struct - assert(regions.size() == 2); - llvm::Type *abiTyp = tm_->makeLLVMTwoElementStructType( - regions[0].abiDirectType, regions[1].abiDirectType); - return CABIParamInfo(abiTyp, ParmDirect, AttrNone, -1); -} diff --git a/bridge/go-llvm-cabi-oracle.h b/bridge/go-llvm-cabi-oracle.h index 67097a1..86b79f5 100644 --- a/bridge/go-llvm-cabi-oracle.h +++ b/bridge/go-llvm-cabi-oracle.h @@ -248,18 +248,4 @@ class CABIOracleARM_AAPCS : public CABIOracleArgumentAnalyzer { bool canPassDirectly(unsigned regsInt, unsigned regsSSE, ABIState &state); }; -class CABIOracleRISC_V : public CABIOracleArgumentAnalyzer { -public: - // Given information on the param types and result type for a - // function, create an oracle object that can answer C ABI - // queries about the function. - CABIOracleRISC_V(TypeManager *typeManager); - CABIParamInfo analyzeABIParam(Btype *pType, ABIState &state); - CABIParamInfo analyzeABIReturn(Btype *resultType, ABIState &state); - -private: - CABIParamDisp classifyArgType(Btype *btype); - bool canPassDirectly(unsigned regsInt, unsigned regsSSE, ABIState &state); -}; - #endif // LLVMGOFRONTEND_GO_LLVM_CABI_ORACLE_H diff --git a/cmake/modules/AutoGenGo.cmake b/cmake/modules/AutoGenGo.cmake index 22f2376..a0a3af6 100644 --- a/cmake/modules/AutoGenGo.cmake +++ b/cmake/modules/AutoGenGo.cmake @@ -375,8 +375,11 @@ function(mkzdefaultcc package outfile ccpath cxxpath) CMAKE_PARSE_ARGUMENTS(ARG "EXPORT" "" "" ${ARGN}) # Construct default driver path - set(driverpath "${GOLLVM_INSTALL_DIR}/bin/llvm-goc") - + if (GOLLVM_DRIVER_DIR) + set(driverpath "${GOLLVM_DRIVER_DIR}/bin/llvm-goc") + else() + set(driverpath "${GOLLVM_INSTALL_DIR}/bin/llvm-goc") + endif() file(REMOVE ${outfile}) file(WRITE ${outfile} "package ${package}\n\n") diff --git a/cmake/modules/GoVars.cmake b/cmake/modules/GoVars.cmake index c8d0e98..5aa2c32 100644 --- a/cmake/modules/GoVars.cmake +++ b/cmake/modules/GoVars.cmake @@ -11,10 +11,6 @@ if( ${llarch} STREQUAL "x86_64" ) # LLVM's "aarch64" is the same as Go's "arm64". elseif( ${llarch} STREQUAL "aarch64" ) set(goarch "arm64") -elseif( ${llarch} STREQUAL "riscv64" ) - # Driver::installedLibDir honors ./lib64 only - # Future change needed (along with those in AddGollvm.cmake) - set(goarch "riscv64") else() message(SEND_ERROR "Arch ${llarch} not yet supported") endif() @@ -31,10 +27,6 @@ elseif( ${llarch} STREQUAL "aarch64" ) # Driver::installedLibDir honors ./lib64 only # Future change needed (along with those in AddGollvm.cmake) set(library_suffix "64") -elseif( ${llarch} STREQUAL "riscv64" ) - # Driver::installedLibDir honors ./lib64 only - # Future change needed (along with those in AddGollvm.cmake) - set(library_suffix "64") else() message(SEND_ERROR "Arch ${llarch} not yet supported") endif() diff --git a/cmake/modules/LibbacktraceUtils.cmake b/cmake/modules/LibbacktraceUtils.cmake index 2c018fd..dc54f18 100644 --- a/cmake/modules/LibbacktraceUtils.cmake +++ b/cmake/modules/LibbacktraceUtils.cmake @@ -11,9 +11,6 @@ function(setup_libbacktrace) elseif( ${goarch} STREQUAL "arm64") set(BACKTRACE_ELF_SIZE 64) set(HAVE_GETIPINFO 1) - elseif( ${goarch} STREQUAL "riscv64") - set(BACKTRACE_ELF_SIZE 64) - set(HAVE_GETIPINFO 1) else() message(SEND_ERROR "Libbacktrace config setup not implemented for ${goarch}") endif() @@ -71,10 +68,6 @@ function(setup_libbacktrace) if(GOLLVM_USE_SPLIT_STACK) string(APPEND libbacktraceflags " -fsplit-stack ${CFPROTECTION_WORKAROUND}") endif() - # Force -funwind-tables to be used for RISC-V so .eh_frame exists for stack unwinding. - if (${goarch} STREQUAL "riscv64") - string(APPEND libbacktraceflags " -funwind-tables") - endif() string(APPEND libbacktraceflags " ${GOLLVM_EXTRA_CFLAGS}") # Object libraries built from libbacktrace sources. diff --git a/cmake/modules/LibffiUtils.cmake b/cmake/modules/LibffiUtils.cmake index a05bbe9..035b647 100644 --- a/cmake/modules/LibffiUtils.cmake +++ b/cmake/modules/LibffiUtils.cmake @@ -9,8 +9,6 @@ function(setup_libffi libffi_srcroot) set(arch_dir "aarch64") elseif(${llarch} STREQUAL "x86_64") set(arch_dir "x86") - elseif(${llarch} STREQUAL "riscv64") - set(arch_dir "riscv") else() message(SEND_ERROR "Arch ${llarch} not yet supported") endif() @@ -37,7 +35,7 @@ function(setup_libffi libffi_srcroot) set(HAVE_64BIT 0) else() set(HAVE_64BIT 1) - if(${llarch} STREQUAL "x86_64") + if(NOT ${llarch} STREQUAL "aarch64") set(HAVE_AS_X86_64_UNWIND_SECTION_TYPE 1) endif() endif() @@ -64,8 +62,6 @@ function(setup_libffi libffi_srcroot) # Set target based on arch. if(HAVE_64BIT AND ${llarch} STREQUAL "aarch64") set(TARGET AARCH64) - elseif(HAVE_64BIT AND ${llarch} STREQUAL "riscv64") - set(TARGET RISCV64) elseif(HAVE_64BIT) set(TARGET X86_64) else() @@ -90,10 +86,6 @@ function(setup_libffi libffi_srcroot) if(GOLLVM_USE_SPLIT_STACK) string(APPEND libffiflags " -fsplit-stack ${CFPROTECTION_WORKAROUND}") endif() - # Force -funwind-tables to be used for RISC-V so .eh_frame exists for stack unwinding. - if (${goarch} STREQUAL "riscv64") - string(APPEND libffiflags " -funwind-tables") - endif() string(APPEND libffiflags " ${GOLLVM_EXTRA_CFLAGS}") # Copy correct version of ffitarget.h to libgo binary root. diff --git a/driver/ArchCpusAttrs.h b/driver/ArchCpusAttrs.h index 424544a..b083dda 100644 --- a/driver/ArchCpusAttrs.h +++ b/driver/ArchCpusAttrs.h @@ -4,7 +4,7 @@ // // in combination with clang: // -// clang version 15.0.0 (git@github.com:plctlab/llvm-project.git ed6894730b4329183dc2fe2c00b6c5b4aa6ed56b) +// clang version 11.0.0 (https://github.com/llvm/llvm-project.git 0160ad802e899c2922bc9b29564080c22eb0908c) // typedef struct { @@ -21,61 +21,54 @@ typedef struct { static const CpuAttrs attrs0[] = { // first entry is default cpu { "x86-64", "+cx8,+fxsr,+mmx,+sse,+sse2,+x87"}, - { "alderlake", "+adx,+aes,+avx,+avx2,+avxvnni,+bmi,+bmi2,+cldemote,+clflushopt,+clwb,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+gfni,+hreset,+invpcid,+kl,+lzcnt,+mmx,+movbe,+movdir64b,+movdiri,+pclmul,+pconfig,+pku,+popcnt,+prfchw,+ptwrite,+rdpid,+rdrnd,+rdseed,+sahf,+serialize,+sgx,+sha,+shstk,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+vaes,+vpclmulqdq,+waitpkg,+widekl,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, { "amdfam10", "+3dnow,+3dnowa,+cx16,+cx8,+fxsr,+lzcnt,+mmx,+popcnt,+prfchw,+sahf,+sse,+sse2,+sse3,+sse4a,+x87"}, { "athlon-fx", "+3dnow,+3dnowa,+cx8,+fxsr,+mmx,+sse,+sse2,+x87"}, { "athlon64", "+3dnow,+3dnowa,+cx8,+fxsr,+mmx,+sse,+sse2,+x87"}, { "athlon64-sse3", "+3dnow,+3dnowa,+cx8,+fxsr,+mmx,+sse,+sse2,+sse3,+x87"}, { "atom", "+cx16,+cx8,+fxsr,+mmx,+movbe,+sahf,+sse,+sse2,+sse3,+ssse3,+x87"}, { "barcelona", "+3dnow,+3dnowa,+cx16,+cx8,+fxsr,+lzcnt,+mmx,+popcnt,+prfchw,+sahf,+sse,+sse2,+sse3,+sse4a,+x87"}, - { "bdver1", "+aes,+avx,+crc32,+cx16,+cx8,+fma4,+fxsr,+lwp,+lzcnt,+mmx,+pclmul,+popcnt,+prfchw,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+x87,+xop,+xsave"}, - { "bdver2", "+aes,+avx,+bmi,+crc32,+cx16,+cx8,+f16c,+fma,+fma4,+fxsr,+lwp,+lzcnt,+mmx,+pclmul,+popcnt,+prfchw,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+tbm,+x87,+xop,+xsave"}, - { "bdver3", "+aes,+avx,+bmi,+crc32,+cx16,+cx8,+f16c,+fma,+fma4,+fsgsbase,+fxsr,+lwp,+lzcnt,+mmx,+pclmul,+popcnt,+prfchw,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+tbm,+x87,+xop,+xsave,+xsaveopt"}, - { "bdver4", "+aes,+avx,+avx2,+bmi,+bmi2,+crc32,+cx16,+cx8,+f16c,+fma,+fma4,+fsgsbase,+fxsr,+lwp,+lzcnt,+mmx,+movbe,+mwaitx,+pclmul,+popcnt,+prfchw,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+tbm,+x87,+xop,+xsave,+xsaveopt"}, + { "bdver1", "+aes,+avx,+cx16,+cx8,+fma4,+fxsr,+lwp,+lzcnt,+mmx,+pclmul,+popcnt,+prfchw,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+x87,+xop,+xsave"}, + { "bdver2", "+aes,+avx,+bmi,+cx16,+cx8,+f16c,+fma,+fma4,+fxsr,+lwp,+lzcnt,+mmx,+pclmul,+popcnt,+prfchw,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+tbm,+x87,+xop,+xsave"}, + { "bdver3", "+aes,+avx,+bmi,+cx16,+cx8,+f16c,+fma,+fma4,+fsgsbase,+fxsr,+lwp,+lzcnt,+mmx,+pclmul,+popcnt,+prfchw,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+tbm,+x87,+xop,+xsave,+xsaveopt"}, + { "bdver4", "+aes,+avx,+avx2,+bmi,+bmi2,+cx16,+cx8,+f16c,+fma,+fma4,+fsgsbase,+fxsr,+lwp,+lzcnt,+mmx,+movbe,+mwaitx,+pclmul,+popcnt,+prfchw,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+tbm,+x87,+xop,+xsave,+xsaveopt"}, { "bonnell", "+cx16,+cx8,+fxsr,+mmx,+movbe,+sahf,+sse,+sse2,+sse3,+ssse3,+x87"}, - { "broadwell", "+adx,+avx,+avx2,+bmi,+bmi2,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"}, + { "broadwell", "+adx,+avx,+avx2,+bmi,+bmi2,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"}, { "btver1", "+cx16,+cx8,+fxsr,+lzcnt,+mmx,+popcnt,+prfchw,+sahf,+sse,+sse2,+sse3,+sse4a,+ssse3,+x87"}, - { "btver2", "+aes,+avx,+bmi,+crc32,+cx16,+cx8,+f16c,+fxsr,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+x87,+xsave,+xsaveopt"}, - { "cannonlake", "+adx,+aes,+avx,+avx2,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512ifma,+avx512vbmi,+avx512vl,+bmi,+bmi2,+clflushopt,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+pku,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sgx,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, - { "cascadelake", "+adx,+aes,+avx,+avx2,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512vl,+avx512vnni,+bmi,+bmi2,+clflushopt,+clwb,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+pku,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, - { "cooperlake", "+adx,+aes,+avx,+avx2,+avx512bf16,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512vl,+avx512vnni,+bmi,+bmi2,+clflushopt,+clwb,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+pku,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, - { "core-avx-i", "+avx,+crc32,+cx16,+cx8,+f16c,+fsgsbase,+fxsr,+mmx,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"}, - { "core-avx2", "+avx,+avx2,+bmi,+bmi2,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"}, + { "btver2", "+aes,+avx,+bmi,+cx16,+cx8,+f16c,+fxsr,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+x87,+xsave,+xsaveopt"}, + { "cannonlake", "+adx,+aes,+avx,+avx2,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512ifma,+avx512vbmi,+avx512vl,+bmi,+bmi2,+clflushopt,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+pku,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sgx,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, + { "cascadelake", "+adx,+aes,+avx,+avx2,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512vl,+avx512vnni,+bmi,+bmi2,+clflushopt,+clwb,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+pku,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, + { "cooperlake", "+adx,+aes,+avx,+avx2,+avx512bf16,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512vl,+avx512vnni,+bmi,+bmi2,+clflushopt,+clwb,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+pku,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, + { "core-avx-i", "+avx,+cx16,+cx8,+f16c,+fsgsbase,+fxsr,+mmx,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"}, + { "core-avx2", "+avx,+avx2,+bmi,+bmi2,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"}, { "core2", "+cx16,+cx8,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+ssse3,+x87"}, - { "corei7", "+crc32,+cx16,+cx8,+fxsr,+mmx,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87"}, - { "corei7-avx", "+avx,+crc32,+cx16,+cx8,+fxsr,+mmx,+pclmul,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"}, - { "goldmont", "+aes,+clflushopt,+crc32,+cx16,+cx8,+fsgsbase,+fxsr,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, - { "goldmont-plus", "+aes,+clflushopt,+crc32,+cx16,+cx8,+fsgsbase,+fxsr,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+ptwrite,+rdpid,+rdrnd,+rdseed,+sahf,+sgx,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, - { "haswell", "+avx,+avx2,+bmi,+bmi2,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"}, - { "icelake-client", "+adx,+aes,+avx,+avx2,+avx512bitalg,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512ifma,+avx512vbmi,+avx512vbmi2,+avx512vl,+avx512vnni,+avx512vpopcntdq,+bmi,+bmi2,+clflushopt,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+gfni,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+pku,+popcnt,+prfchw,+rdpid,+rdrnd,+rdseed,+sahf,+sgx,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+vaes,+vpclmulqdq,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, - { "icelake-server", "+adx,+aes,+avx,+avx2,+avx512bitalg,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512ifma,+avx512vbmi,+avx512vbmi2,+avx512vl,+avx512vnni,+avx512vpopcntdq,+bmi,+bmi2,+clflushopt,+clwb,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+gfni,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+pconfig,+pku,+popcnt,+prfchw,+rdpid,+rdrnd,+rdseed,+sahf,+sgx,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+vaes,+vpclmulqdq,+wbnoinvd,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, - { "ivybridge", "+avx,+crc32,+cx16,+cx8,+f16c,+fsgsbase,+fxsr,+mmx,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"}, + { "corei7", "+cx16,+cx8,+fxsr,+mmx,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87"}, + { "corei7-avx", "+avx,+cx16,+cx8,+fxsr,+mmx,+pclmul,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"}, + { "goldmont", "+aes,+clflushopt,+cx16,+cx8,+fsgsbase,+fxsr,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, + { "goldmont-plus", "+aes,+clflushopt,+cx16,+cx8,+fsgsbase,+fxsr,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+ptwrite,+rdpid,+rdrnd,+rdseed,+sahf,+sgx,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, + { "haswell", "+avx,+avx2,+bmi,+bmi2,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"}, + { "icelake-client", "+adx,+aes,+avx,+avx2,+avx512bitalg,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512ifma,+avx512vbmi,+avx512vbmi2,+avx512vl,+avx512vnni,+avx512vpopcntdq,+bmi,+bmi2,+clflushopt,+clwb,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+gfni,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+pku,+popcnt,+prfchw,+rdpid,+rdrnd,+rdseed,+sahf,+sgx,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+vaes,+vpclmulqdq,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, + { "icelake-server", "+adx,+aes,+avx,+avx2,+avx512bitalg,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512ifma,+avx512vbmi,+avx512vbmi2,+avx512vl,+avx512vnni,+avx512vpopcntdq,+bmi,+bmi2,+clflushopt,+clwb,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+gfni,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+pconfig,+pku,+popcnt,+prfchw,+rdpid,+rdrnd,+rdseed,+sahf,+sgx,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+vaes,+vpclmulqdq,+wbnoinvd,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, + { "ivybridge", "+avx,+cx16,+cx8,+f16c,+fsgsbase,+fxsr,+mmx,+pclmul,+popcnt,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"}, { "k8", "+3dnow,+3dnowa,+cx8,+fxsr,+mmx,+sse,+sse2,+x87"}, { "k8-sse3", "+3dnow,+3dnowa,+cx8,+fxsr,+mmx,+sse,+sse2,+sse3,+x87"}, - { "knl", "+adx,+aes,+avx,+avx2,+avx512cd,+avx512er,+avx512f,+avx512pf,+bmi,+bmi2,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+prefetchwt1,+prfchw,+rdrnd,+rdseed,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"}, - { "knm", "+adx,+aes,+avx,+avx2,+avx512cd,+avx512er,+avx512f,+avx512pf,+avx512vpopcntdq,+bmi,+bmi2,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+prefetchwt1,+prfchw,+rdrnd,+rdseed,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"}, - { "nehalem", "+crc32,+cx16,+cx8,+fxsr,+mmx,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87"}, + { "knl", "+adx,+aes,+avx,+avx2,+avx512cd,+avx512er,+avx512f,+avx512pf,+bmi,+bmi2,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+prefetchwt1,+prfchw,+rdrnd,+rdseed,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"}, + { "knm", "+adx,+aes,+avx,+avx2,+avx512cd,+avx512er,+avx512f,+avx512pf,+avx512vpopcntdq,+bmi,+bmi2,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+prefetchwt1,+prfchw,+rdrnd,+rdseed,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"}, + { "nehalem", "+cx16,+cx8,+fxsr,+mmx,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87"}, { "nocona", "+cx16,+cx8,+fxsr,+mmx,+sse,+sse2,+sse3,+x87"}, { "opteron", "+3dnow,+3dnowa,+cx8,+fxsr,+mmx,+sse,+sse2,+x87"}, { "opteron-sse3", "+3dnow,+3dnowa,+cx8,+fxsr,+mmx,+sse,+sse2,+sse3,+x87"}, { "penryn", "+cx16,+cx8,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87"}, - { "rocketlake", "+adx,+aes,+avx,+avx2,+avx512bitalg,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512ifma,+avx512vbmi,+avx512vbmi2,+avx512vl,+avx512vnni,+avx512vpopcntdq,+bmi,+bmi2,+clflushopt,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+gfni,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+pku,+popcnt,+prfchw,+rdpid,+rdrnd,+rdseed,+sahf,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+vaes,+vpclmulqdq,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, - { "sandybridge", "+avx,+crc32,+cx16,+cx8,+fxsr,+mmx,+pclmul,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"}, - { "sapphirerapids", "+adx,+aes,+amx-bf16,+amx-int8,+amx-tile,+avx,+avx2,+avx512bf16,+avx512bitalg,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512fp16,+avx512ifma,+avx512vbmi,+avx512vbmi2,+avx512vl,+avx512vnni,+avx512vp2intersect,+avx512vpopcntdq,+avxvnni,+bmi,+bmi2,+cldemote,+clflushopt,+clwb,+crc32,+cx16,+cx8,+enqcmd,+f16c,+fma,+fsgsbase,+fxsr,+gfni,+invpcid,+lzcnt,+mmx,+movbe,+movdir64b,+movdiri,+pclmul,+pconfig,+pku,+popcnt,+prfchw,+ptwrite,+rdpid,+rdrnd,+rdseed,+sahf,+serialize,+sgx,+sha,+shstk,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+tsxldtrk,+uintr,+vaes,+vpclmulqdq,+waitpkg,+wbnoinvd,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, - { "silvermont", "+crc32,+cx16,+cx8,+fxsr,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87"}, - { "skx", "+adx,+aes,+avx,+avx2,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512vl,+bmi,+bmi2,+clflushopt,+clwb,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+pku,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, - { "skylake", "+adx,+aes,+avx,+avx2,+bmi,+bmi2,+clflushopt,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sgx,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, - { "skylake-avx512", "+adx,+aes,+avx,+avx2,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512vl,+bmi,+bmi2,+clflushopt,+clwb,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+pku,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, - { "slm", "+crc32,+cx16,+cx8,+fxsr,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87"}, - { "tigerlake", "+adx,+aes,+avx,+avx2,+avx512bitalg,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512ifma,+avx512vbmi,+avx512vbmi2,+avx512vl,+avx512vnni,+avx512vp2intersect,+avx512vpopcntdq,+bmi,+bmi2,+clflushopt,+clwb,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+gfni,+invpcid,+kl,+lzcnt,+mmx,+movbe,+movdir64b,+movdiri,+pclmul,+pku,+popcnt,+prfchw,+rdpid,+rdrnd,+rdseed,+sahf,+sgx,+sha,+shstk,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+vaes,+vpclmulqdq,+widekl,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, - { "tremont", "+aes,+clflushopt,+clwb,+crc32,+cx16,+cx8,+fsgsbase,+fxsr,+gfni,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+ptwrite,+rdpid,+rdrnd,+rdseed,+sahf,+sgx,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, - { "westmere", "+crc32,+cx16,+cx8,+fxsr,+mmx,+pclmul,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87"}, - { "x86-64-v2", "+crc32,+cx16,+cx8,+fxsr,+mmx,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87"}, - { "x86-64-v3", "+avx,+avx2,+bmi,+bmi2,+crc32,+cx16,+cx8,+f16c,+fma,+fxsr,+lzcnt,+mmx,+movbe,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave"}, - { "x86-64-v4", "+avx,+avx2,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512vl,+bmi,+bmi2,+crc32,+cx16,+cx8,+f16c,+fma,+fxsr,+lzcnt,+mmx,+movbe,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave"}, - { "znver1", "+adx,+aes,+avx,+avx2,+bmi,+bmi2,+clflushopt,+clzero,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+lzcnt,+mmx,+movbe,+mwaitx,+pclmul,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, - { "znver2", "+adx,+aes,+avx,+avx2,+bmi,+bmi2,+clflushopt,+clwb,+clzero,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+lzcnt,+mmx,+movbe,+mwaitx,+pclmul,+popcnt,+prfchw,+rdpid,+rdrnd,+rdseed,+sahf,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+wbnoinvd,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, - { "znver3", "+adx,+aes,+avx,+avx2,+bmi,+bmi2,+clflushopt,+clwb,+clzero,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+mwaitx,+pclmul,+pku,+popcnt,+prfchw,+rdpid,+rdrnd,+rdseed,+sahf,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+vaes,+vpclmulqdq,+wbnoinvd,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, + { "sandybridge", "+avx,+cx16,+cx8,+fxsr,+mmx,+pclmul,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt"}, + { "silvermont", "+cx16,+cx8,+fxsr,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87"}, + { "skx", "+adx,+aes,+avx,+avx2,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512vl,+bmi,+bmi2,+clflushopt,+clwb,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+pku,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, + { "skylake", "+adx,+aes,+avx,+avx2,+bmi,+bmi2,+clflushopt,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sgx,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, + { "skylake-avx512", "+adx,+aes,+avx,+avx2,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512vl,+bmi,+bmi2,+clflushopt,+clwb,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+invpcid,+lzcnt,+mmx,+movbe,+pclmul,+pku,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, + { "slm", "+cx16,+cx8,+fxsr,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+rdrnd,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87"}, + { "tigerlake", "+adx,+aes,+avx,+avx2,+avx512bitalg,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512ifma,+avx512vbmi,+avx512vbmi2,+avx512vl,+avx512vnni,+avx512vp2intersect,+avx512vpopcntdq,+bmi,+bmi2,+clflushopt,+clwb,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+gfni,+invpcid,+lzcnt,+mmx,+movbe,+movdir64b,+movdiri,+pclmul,+pku,+popcnt,+prfchw,+rdpid,+rdrnd,+rdseed,+sahf,+sgx,+sha,+shstk,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+vaes,+vpclmulqdq,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, + { "tremont", "+aes,+clflushopt,+clwb,+cx16,+cx8,+fsgsbase,+fxsr,+gfni,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+ptwrite,+rdpid,+rdrnd,+rdseed,+sahf,+sgx,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, + { "westmere", "+cx16,+cx8,+fxsr,+mmx,+pclmul,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87"}, + { "znver1", "+adx,+aes,+avx,+avx2,+bmi,+bmi2,+clflushopt,+clzero,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+lzcnt,+mmx,+movbe,+mwaitx,+pclmul,+popcnt,+prfchw,+rdrnd,+rdseed,+sahf,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, + { "znver2", "+adx,+aes,+avx,+avx2,+bmi,+bmi2,+clflushopt,+clwb,+clzero,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+lzcnt,+mmx,+movbe,+mwaitx,+pclmul,+popcnt,+prfchw,+rdpid,+rdrnd,+rdseed,+sahf,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+wbnoinvd,+x87,+xsave,+xsavec,+xsaveopt,+xsaves"}, { "", "" } // sentinel }; @@ -84,80 +77,52 @@ static const CpuAttrs attrs1[] = { // first entry is default cpu { "generic", "+neon"}, { "a64fx", "+aes,+crc,+crypto,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rdm,+sha2,+sve,+v8.2a"}, - { "apple-a10", "+aes,+crc,+crypto,+fp-armv8,+neon,+rdm,+sha2,+v8a,+zcm,+zcz"}, - { "apple-a11", "+aes,+crc,+crypto,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rdm,+sha2,+v8.2a,+zcm,+zcz"}, + { "apple-a10", "+aes,+crc,+crypto,+fp-armv8,+neon,+rdm,+sha2,+zcm,+zcz"}, + { "apple-a11", "+aes,+crc,+crypto,+fp-armv8,+lse,+neon,+ras,+rdm,+sha2,+v8.2a,+zcm,+zcz"}, { "apple-a12", "+aes,+crc,+crypto,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.3a,+zcm,+zcz"}, { "apple-a13", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+sha3,+sm4,+v8.4a,+zcm,+zcz"}, - { "apple-a14", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.5a,+zcm,+zcz"}, - { "apple-a7", "+aes,+crypto,+fp-armv8,+neon,+sha2,+v8a,+zcm,+zcz"}, - { "apple-a8", "+aes,+crypto,+fp-armv8,+neon,+sha2,+v8a,+zcm,+zcz"}, - { "apple-a9", "+aes,+crypto,+fp-armv8,+neon,+sha2,+v8a,+zcm,+zcz"}, - { "apple-m1", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.5a,+zcm,+zcz"}, + { "apple-a7", "+aes,+crypto,+fp-armv8,+neon,+sha2,+zcm,+zcz"}, + { "apple-a8", "+aes,+crypto,+fp-armv8,+neon,+sha2,+zcm,+zcz"}, + { "apple-a9", "+aes,+crypto,+fp-armv8,+neon,+sha2,+zcm,+zcz"}, { "apple-s4", "+aes,+crc,+crypto,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.3a,+zcm,+zcz"}, { "apple-s5", "+aes,+crc,+crypto,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.3a,+zcm,+zcz"}, { "carmel", "+aes,+crc,+crypto,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rdm,+sha2,+v8.2a"}, - { "cortex-a34", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2,+v8a"}, - { "cortex-a35", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2,+v8a"}, - { "cortex-a510", "+crc,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+lse,+neon,+pauth,+ras,+rcpc,+rdm,+sve,+sve2,+sve2-bitperm,+v9a"}, - { "cortex-a53", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2,+v8a"}, + { "cortex-a34", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2"}, + { "cortex-a35", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2"}, + { "cortex-a53", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2"}, { "cortex-a55", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.2a"}, - { "cortex-a57", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2,+v8a"}, + { "cortex-a57", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2"}, { "cortex-a65", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.2a"}, { "cortex-a65ae", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.2a"}, - { "cortex-a710", "+crc,+dotprod,+flagm,+fp-armv8,+fp16fml,+fullfp16,+lse,+neon,+pauth,+ras,+rcpc,+rdm,+sve,+sve2,+sve2-bitperm,+v9a"}, - { "cortex-a72", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2,+v8a"}, - { "cortex-a73", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2,+v8a"}, + { "cortex-a72", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2"}, + { "cortex-a73", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2"}, { "cortex-a75", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.2a"}, { "cortex-a76", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.2a"}, { "cortex-a76ae", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.2a"}, { "cortex-a77", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.2a"}, { "cortex-a78", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.2a"}, - { "cortex-a78c", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.2a"}, - { "cortex-r82", "+crc,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+v8r"}, { "cortex-x1", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.2a"}, - { "cortex-x1c", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+pauth,+ras,+rcpc,+rdm,+sha2,+v8.2a"}, - { "cortex-x2", "+crc,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+lse,+neon,+pauth,+ras,+rcpc,+rdm,+sve,+sve2,+sve2-bitperm,+v9a"}, - { "cyclone", "+aes,+crypto,+fp-armv8,+neon,+sha2,+v8a,+zcm,+zcz"}, - { "exynos-m3", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2,+v8a"}, + { "cyclone", "+aes,+crypto,+fp-armv8,+neon,+sha2,+zcm,+zcz"}, + { "exynos-m3", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2"}, { "exynos-m4", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rdm,+sha2,+v8.2a"}, { "exynos-m5", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rdm,+sha2,+v8.2a"}, - { "falkor", "+aes,+crc,+crypto,+fp-armv8,+neon,+rdm,+sha2,+v8a"}, - { "kryo", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2,+v8a"}, - { "neoverse-512tvb", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+sha3,+sm4,+sve,+v8.4a"}, + { "falkor", "+aes,+crc,+crypto,+fp-armv8,+neon,+rdm,+sha2"}, + { "kryo", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2"}, { "neoverse-e1", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+v8.2a"}, { "neoverse-n1", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+spe,+v8.2a"}, - { "neoverse-n2", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+sve,+sve2,+sve2-bitperm,+v8.5a"}, - { "neoverse-v1", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+sha3,+sm4,+sve,+v8.4a"}, { "saphira", "+aes,+crc,+crypto,+fp-armv8,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+spe,+v8.3a"}, - { "thunderx", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2,+spe,+v8a"}, + { "thunderx", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2,+spe"}, { "thunderx2t99", "+aes,+crc,+crypto,+fp-armv8,+lse,+neon,+rdm,+sha2,+v8.1a"}, { "thunderx3t110", "+aes,+crc,+crypto,+fp-armv8,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+spe,+v8.3a"}, - { "thunderxt81", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2,+spe,+v8a"}, - { "thunderxt83", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2,+spe,+v8a"}, - { "thunderxt88", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2,+spe,+v8a"}, + { "thunderxt81", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2,+spe"}, + { "thunderxt83", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2,+spe"}, + { "thunderxt88", "+aes,+crc,+crypto,+fp-armv8,+neon,+sha2,+spe"}, { "tsv110", "+aes,+crc,+crypto,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+lse,+neon,+ras,+rdm,+sha2,+spe,+v8.2a"}, { "", "" } // sentinel }; -// triple: riscv64-unknown-linux-gnu -static const CpuAttrs attrs2[] = { - // first entry is default cpu - { "", "+64bit,+a,+c,+d,+f,+m,+relax,-save-restore"}, - { "generic-rv64", "+64bit,+a,+c,+d,+f,+m,+relax,-save-restore"}, - { "rocket-rv64", "+64bit,+a,+c,+d,+f,+m,+relax,-save-restore"}, - { "sifive-7-rv64", "+64bit,+a,+c,+d,+f,+m,+relax,-save-restore"}, - { "sifive-s21", "+64bit,+a,+c,+m,+relax,-save-restore"}, - { "sifive-s51", "+64bit,+a,+c,+m,+relax,-save-restore"}, - { "sifive-s54", "+64bit,+a,+c,+d,+f,+m,+relax,-save-restore"}, - { "sifive-s76", "+64bit,+a,+c,+d,+f,+m,+relax,-save-restore"}, - { "sifive-u54", "+64bit,+a,+c,+d,+f,+m,+relax,-save-restore"}, - { "sifive-u74", "+64bit,+a,+c,+d,+f,+m,+relax,-save-restore"}, - { "", "" } // sentinel -}; - const TripleCpus triples[] = { { "x86_64-unknown-linux-gnu", &attrs0[0] }, { "aarch64-unknown-linux-gnu", &attrs1[0] }, - { "riscv64-unknown-linux-gnu", &attrs2[0] }, { "", nullptr } // sentinel }; diff --git a/driver/CompileGo.cpp b/driver/CompileGo.cpp index 48301da..3312a7a 100644 --- a/driver/CompileGo.cpp +++ b/driver/CompileGo.cpp @@ -413,9 +413,6 @@ bool CompileGoImpl::setup(const Action &jobAction) TargetOptions Options; - if (triple_.getArch() == llvm::Triple::riscv64) - Options.MCOptions.ABIName = "lp64d"; - auto jat = jobAction.type(); assert(jat == Action::A_CompileAndAssemble || jat == Action::A_Compile); @@ -863,10 +860,9 @@ bool CompileGoImpl::invokeBackEnd(const Action &jobAction) createTargetTransformInfoWrapperPass(target_->getTargetIRAnalysis())); createPasses(modulePasses, functionPasses); - // Disable inlining getg in some cases on x86_64 and RISC-V. - if (triple_.getArch() == llvm::Triple::x86_64 || - triple_.getArch() == llvm::Triple::riscv64) { - modulePasses.add(createGoSafeGetgPass()); + // Disable inlining getg in some cases on x86_64. + if (triple_.getArch() == llvm::Triple::x86_64) { + modulePasses.add(createGoSafeGetgPass()); } // Add statepoint insertion pass to the end of optimization pipeline, diff --git a/driver/Driver.cpp b/driver/Driver.cpp index c8a7db5..777cc2b 100644 --- a/driver/Driver.cpp +++ b/driver/Driver.cpp @@ -418,6 +418,10 @@ ToolChain *Driver::setup() triple_ = defaultTargetTriple; if (const opt::Arg *arg = args_.getLastArg(gollvm::options::OPT_target_EQ)) triple_ = Triple(Triple::normalize(arg->getValue())); + if (triple_ != defaultTargetTriple) { + errs() << progname_ << ": error: gollvm doesn't support cross compiling yet\n"; + return nullptr; + } // Honor -dumpmachine if (args_.hasArg(gollvm::options::OPT_dumpmachine)) { diff --git a/driver/GccUtils.cpp b/driver/GccUtils.cpp index 01fc06c..f8f8c8e 100644 --- a/driver/GccUtils.cpp +++ b/driver/GccUtils.cpp @@ -190,16 +190,6 @@ bool GCCInstallationDetector::selectLibDirs(state &s) s.triple.setTriple(triple_.str()); s.suffixes = {""}; break; - case llvm::Triple::riscv64: - s.tripleAliases = { - triple_.str(), - "riscv64-linux-gnu", "riscv64-unknown-linux-gnu" - }; - s.libdirs.push_back("/lib"); - s.libdirs.push_back("/lib64"); - s.triple.setTriple(triple_.str()); - s.suffixes = {""}; - break; default: llvm::errs() << "error: unsupported triple " << triple_.str() << " in " << __FUNCTION__ << "\n"; diff --git a/driver/GnuTools.cpp b/driver/GnuTools.cpp index ca80bef..ea148f5 100644 --- a/driver/GnuTools.cpp +++ b/driver/GnuTools.cpp @@ -218,9 +218,6 @@ void Linker::addLDM(llvm::opt::ArgStringList &cmdArgs) // Currently only support linux/arm64 cmdArgs.push_back("aarch64linux"); break; - case llvm::Triple::riscv64: - cmdArgs.push_back("elf64lriscv"); - break; default: // unhandled architecture cmdArgs.push_back("%unknown%"); diff --git a/driver/IntegAssembler.cpp b/driver/IntegAssembler.cpp index 77b42f8..a40be9f 100644 --- a/driver/IntegAssembler.cpp +++ b/driver/IntegAssembler.cpp @@ -179,8 +179,6 @@ bool IntegAssemblerImpl::invokeAssembler() assert(MRI && "Unable to create target register info!"); MCTargetOptions MCOptions; - if (triple_.getArch() == llvm::Triple::riscv64) - MCOptions.ABIName = "lp64d"; std::unique_ptr MAI( TheTarget->createMCAsmInfo(*MRI, Trip, MCOptions)); assert(MAI && "Unable to create target asm info!"); diff --git a/driver/LinuxToolChain.cpp b/driver/LinuxToolChain.cpp index 2c304ca..a12b794 100644 --- a/driver/LinuxToolChain.cpp +++ b/driver/LinuxToolChain.cpp @@ -145,10 +145,6 @@ std::string Linux::getDynamicLinker(const llvm::opt::ArgList &args) Loader = "ld-linux-x86-64.so.2"; break; } - case llvm::Triple::riscv64: - LibDir = "lib"; - Loader = "ld-linux-riscv64-lp64d.so.1"; - break; } if (auto *Arg = args.getLastArg(gollvm::options::OPT_sysroot_EQ)) { std::string Sysroot = Arg->getValue(); diff --git a/libgo/CMakeLists.txt b/libgo/CMakeLists.txt index 8585c90..6fcdff6 100644 --- a/libgo/CMakeLists.txt +++ b/libgo/CMakeLists.txt @@ -86,9 +86,6 @@ set(tmp_libgo_extra_gocflags ${GOLLVM_EXTRA_GOCFLAGS}) if(GOLLVM_EXTRA_GOCFLAGS) string(REPLACE " " ";" libgo_extra_gocflags ${tmp_libgo_extra_gocflags}) endif() -if (${llarch} STREQUAL "riscv64") - string(APPEND libgo_extra_gocflags ";-latomic") -endif() if(NOT GOLLVM_USE_SPLIT_STACK) list(APPEND libgo_extra_gocflags "-fno-split-stack") endif() @@ -513,7 +510,7 @@ list(APPEND runtimecfiles "go/syscall/signame.c" "go/syscall/wait.c") -if (${goarch} STREQUAL "amd64") +if (NOT ${goarch} STREQUAL "arm64") list(APPEND runtimecfiles "go/golang.org/x/sys/cpu/cpu_gccgo_x86.c") endif() @@ -533,7 +530,6 @@ endforeach() # go-wrapper.c is not in gofrontend/libgo list(APPEND runtimecpaths "${GOLLVM_SOURCE_DIR}/libgo/runtime/go-wrappers.c") - # Compiler flags for C files in the runtime. set(baseopts "-g -Wno-zero-length-array ") if(GOLLVM_USE_SPLIT_STACK) @@ -542,10 +538,6 @@ endif() foreach(def ${basedefines}) string(APPEND baseopts "${def} ") endforeach() -# Force -funwind-tables to be used for RISC-V so .eh_frame exists for stack unwinding. -if (${goarch} STREQUAL "riscv64") - string(APPEND baseopts "-funwind-tables ") -endif() string(APPEND baseopts "${GOLLVM_EXTRA_CFLAGS} ") # Special flags required for aeshash.c (functions in this file are called @@ -553,8 +545,6 @@ string(APPEND baseopts "${GOLLVM_EXTRA_CFLAGS} ") # specific architectural features). if (${goarch} STREQUAL "arm64") set_source_files_properties(${libgo_csrcroot}/runtime/aeshash.c PROPERTIES COMPILE_FLAGS "-march=armv8-a+crypto") -elseif (${goarch} STREQUAL "riscv64") - set_source_files_properties(${libgo_csrcroot}/runtime/aeshash.c PROPERTIES COMPILE_FLAGS "-march=rv64gc") else() set_source_files_properties(${libgo_csrcroot}/runtime/aeshash.c PROPERTIES COMPILE_FLAGS "-maes -mssse3") endif() diff --git a/tools/capture-fcn-attributes.go b/tools/capture-fcn-attributes.go index d50a827..545d7cd 100644 --- a/tools/capture-fcn-attributes.go +++ b/tools/capture-fcn-attributes.go @@ -87,7 +87,6 @@ void Add512(vstuff *v) { var supportedTriples []string = []string{ "x86_64-unknown-linux-gnu", "aarch64-unknown-linux-gnu", - "riscv64-unknown-linux-gnu", } var ( diff --git a/unittests/BackendCore/BackendCABIOracleTests.cpp b/unittests/BackendCore/BackendCABIOracleTests.cpp index aaa9589..3f3c902 100644 --- a/unittests/BackendCore/BackendCABIOracleTests.cpp +++ b/unittests/BackendCore/BackendCABIOracleTests.cpp @@ -438,190 +438,6 @@ TEST(BackendCABIOracleTests, ExtendedArm64) { } } -TEST(BackendCABIOracleTests, ExtendedRV64) { - LLVMContext C; - std::unique_ptr bep( - new Llvm_backend(C, nullptr, nullptr, 0, llvm::Triple(), llvm::CallingConv::C)); - Llvm_backend *be = bep.get(); - - Btype *bi8t = be->integer_type(false, 8); - Btype *bu8t = be->integer_type(true, 8); - Btype *bu64t = be->integer_type(true, 64); - Btype *bu32t = be->integer_type(true, 32); - Btype *bi16t = be->integer_type(false, 16); - Btype *bf32t = be->float_type(32); - Btype *bf64t = be->float_type(64); - Btype *bpu64t = be->pointer_type(bu64t); - Btype *bpf64t = be->pointer_type(bf64t); - Btype *st0 = mkBackendStruct(be, nullptr); - Btype *st1 = mkBackendStruct(be, bi8t, "a", bu8t, "b", bf32t, "c", nullptr); - Btype *st2 = mkBackendStruct(be, bf64t, "f1", bf64t, "f2", nullptr); - Btype *st3 = mkBackendStruct(be, st2, "f1", bi8t, "f2", nullptr); - Btype *st4 = mkBackendStruct(be, bf32t, "f1", bf32t, "f2", nullptr); - Btype *st5 = mkBackendStruct(be, bf32t, "f1", nullptr); - Btype *st6 = mkBackendStruct(be, bf32t, "f1", bi8t, "a", bu8t, "b", - bu64t, "c", nullptr); - Btype *st7 = mkBackendStruct(be, bf32t, "f1", bu32t, "f2", nullptr); - Btype *st8 = mkBackendStruct(be, bi8t, "f1", bi16t, "f2", st7, "f3", nullptr); - Btype *stii = mkBackendStruct(be, bu64t, "a", bu64t, "b", nullptr); - Btype *stip = mkBackendStruct(be, bu64t, "a", bpu64t, "b", nullptr); - Btype *stpi = mkBackendStruct(be, bpu64t, "a", bu64t, "b", nullptr); - Btype *stpp = mkBackendStruct(be, bpu64t, "a", bpu64t, "b", nullptr); - Btype *at0 = be->array_type(bu32t, mkInt64Const(be, int64_t(0))); - Btype *at1 = be->array_type(bu32t, mkInt64Const(be, int64_t(1))); - Btype *at2 = be->array_type(bu32t, mkInt64Const(be, int64_t(3))); - Btype *at3 = be->array_type(bu8t, mkInt64Const(be, int64_t(16))); - - struct FcnItem { - FcnItem(const std::vector &r, - const std::vector &p, - const char *d, const char *t) - : results(r), parms(p), expDump(d), expTyp(t) { } - std::vector results; - std::vector parms; - const char *expDump; - const char *expTyp; - }; - - Btype *nt = nullptr; - std::vector items = { - - // 1 - FcnItem( { }, { }, - "Return: Ignore { void } sigOffset: -1 " - "Param 1: Direct AttrNest { i8* } sigOffset: 0", - "void (i8*)"), - - // 2 - FcnItem( { bi8t }, { }, - "Return: Direct AttrSext { i8 } sigOffset: -1 " - "Param 1: Direct AttrNest { i8* } sigOffset: 0", - "i8 (i8*)"), - - // 3 - FcnItem( { }, { bi8t }, - "Return: Ignore { void } sigOffset: -1 " - "Param 1: Direct AttrNest { i8* } sigOffset: 0 " - "Param 2: Direct AttrSext { i8 } sigOffset: 1", - "void (i8*, i8)"), - - // 4 - FcnItem( { }, { st5, bpf64t }, - "Return: Ignore { void } sigOffset: -1 " - "Param 1: Direct AttrNest { i8* } sigOffset: 0 " - "Param 2: Direct { float } sigOffset: 1 " - "Param 3: Direct { double* } sigOffset: 2", - "void (i8*, float, double*)"), - - // 5 - FcnItem({ bi8t, bf64t }, { bi8t, bu8t, st0 }, - "Return: Direct { { i8, double } } sigOffset: -1 " - "Param 1: Direct AttrNest { i8* } sigOffset: 0 " - "Param 2: Direct AttrSext { i8 } sigOffset: 1 " - "Param 3: Direct AttrZext { i8 } sigOffset: 2 " - "Param 4: Ignore { void } sigOffset: -1", - "{ i8, double } (i8*, i8, i8)"), - - // 6 - FcnItem({ st2 }, { st2, st0, st4, st1 }, - "Return: Direct { { double, double } } sigOffset: -1 " - "Param 1: Direct AttrNest { i8* } sigOffset: 0 " - "Param 2: Direct { double, double } sigOffset: 1 " - "Param 3: Ignore { void } sigOffset: -1 " - "Param 4: Direct { { float, float } } sigOffset: 3 " - "Param 5: Direct { i64 } sigOffset: 4 ", - "{ double, double } (i8*, double, double, { float, float }, i64)"), - - // 7 - FcnItem({ st3 }, { st3, st0, bu8t }, - "Return: Indirect AttrStructReturn { { { double, double }, i8 }* } sigOffset: 0 " - "Param 1: Direct AttrNest { i8* } sigOffset: 1 " - "Param 2: Indirect AttrByVal { { { double, double }, i8 }* } sigOffset: 2 " - "Param 3: Ignore { void } sigOffset: -1 " - "Param 4: Direct AttrZext { i8 } sigOffset: 3 ", - "void ({ { double, double }, i8 }*, i8*, " - "{ { double, double }, i8 }*, i8)"), - - // 8 - FcnItem( { st6 }, { st6, st6 }, - "Return: Direct { { i64, i64 } } sigOffset: -1 " - "Param 1: Direct AttrNest { i8* } sigOffset: 0 " - "Param 2: Direct { i64, i64 } sigOffset: 1 " - "Param 3: Direct { i64, i64 } sigOffset: 3", - "{ i64, i64 } (i8*, i64, i64, i64, i64)"), - - // 9 - FcnItem( { st8 }, { st8 }, - "Return: Direct { { i64, i32 } } sigOffset: -1 " - "Param 1: Direct AttrNest { i8* } sigOffset: 0 " - "Param 2: Direct { i64, i32 } sigOffset: 1", - "{ i64, i32 } (i8*, i64, i32)"), - - // 10 - FcnItem( { at0 }, { at1 }, - "Return: Ignore { void } sigOffset: -1 " - "Param 1: Direct AttrNest { i8* } sigOffset: 0 " - "Param 2: Direct { i32 } sigOffset: 1", - "void (i8*, i32)"), - - // 11 - FcnItem( { at2 }, { at3 }, - "Return: Direct { { i64, i32 } } sigOffset: -1 " - "Param 1: Direct AttrNest { i8* } sigOffset: 0 " - "Param 2: Direct { i64, i64 } sigOffset: 1", - "{ i64, i32 } (i8*, i64, i64)"), - - // 12 - // Make sure pointerness is preserved. - FcnItem( { stip }, { stii, stpp, stpi }, - "Return: Direct { { i64, i8* } } sigOffset: -1 " - "Param 1: Direct AttrNest { i8* } sigOffset: 0 " - "Param 2: Direct { i64, i64 } sigOffset: 1 " - "Param 3: Direct { i8*, i8* } sigOffset: 3 " - "Param 4: Direct { i8*, i64 } sigOffset: 5", - "{ i64, i8* } (i8*, i64, i64, i8*, i8*, i8*, i64)"), - }; - - unsigned count = 1; - for (auto &item : items) { - std::vector results; - std::vector params; - for (auto &r : item.results) - results.push_back(mkid(r)); - for (auto &p : item.parms) - params.push_back(mkid(p)); - Btype *rt = nullptr; - if (results.size() > 1) - rt = be->struct_type(results); - Btype *t = be->function_type(mkid(nt), params, results, rt, Location()); - BFunctionType *bft = t->castToBFunctionType(); - CABIOracle cab(bft, be->typeManager()); - - { - std::string reason; - bool equal = difftokens(item.expDump, cab.toString(), reason); - EXPECT_EQ("pass", equal ? "pass" : reason); - if (!equal) { - std::cerr << "count: " << count << "\n"; - std::cerr << "exp:\n" << item.expDump << "\n"; - std::cerr << "act:\n" << cab.toString() << "\n"; - } - } - { - std::string reason; - std::string result(repr(cab.getFunctionTypeForABI())); - bool equal = difftokens(item.expTyp, result, reason); - EXPECT_EQ("pass", equal ? "pass" : reason); - if (!equal) { - std::cerr << "count: " << count << "\n"; - std::cerr << "exp:\n" << item.expTyp << "\n"; - std::cerr << "act:\n" << result << "\n"; - } - } - count++; - } -} - TEST(BackendCABIOracleTests, RecursiveCall1Amd64) { FcnTestHarness h(gollvm::driver::CallingConvId::X86_64_SysV); Llvm_backend *be = h.be(); @@ -869,131 +685,6 @@ TEST(BackendCABIOracleTests, RecursiveCall1Arm64) { EXPECT_FALSE(broken && "Module failed to verify."); } -TEST(BackendCABIOracleTests, RecursiveCall1RV64) { - FcnTestHarness h(llvm::CallingConv::C); - Llvm_backend *be = h.be(); - - // type s1 struct { - // f1, f2 float32 - // i1, i2, i3 int16 - // } - // type s2 struct { - // k float64 - // f1, f2 float32 - // } - // type s3 struct { - // f1, s1 - // f2, s2 - // } - // type s4 struct { - // } - // func foo(x s1, y s2, z s4, sm1 uint8, sm2 int8, w s3) s2 { - // if (sm1 == 0) { - // return y - // } - // return foo(x, y, z, sm1-1, sm2, w) - // } - // - - // Create struct types - Btype *bf32t = be->float_type(32); - Btype *bf64t = be->float_type(64); - Btype *bi16t = be->integer_type(false, 16); - Btype *bi8t = be->integer_type(false, 8); - Btype *bu8t = be->integer_type(true, 8); - Btype *s1 = mkBackendStruct(be, bf32t, "f1", bf32t, "f2", - bi16t, "i1", bi16t, "i2", bi16t, "i3", nullptr); - Btype *s2 = mkBackendStruct(be, bf64t, "k", bf32t, "f1", bf32t, "f2", - nullptr); - Btype *s3 = mkBackendStruct(be, s1, "f1", s2, "f2", nullptr); - Btype *s4 = mkBackendStruct(be, nullptr); - - // Create function type - BFunctionType *befty1 = mkFuncTyp(be, - L_PARM, s1, - L_PARM, s2, - L_PARM, s4, - L_PARM, bu8t, - L_PARM, bi8t, - L_PARM, s3, - L_RES, s2, - L_END); - Bfunction *func = h.mkFunction("foo", befty1); - - // sm1 == 0 - Bvariable *p3 = func->getNthParamVar(3); - Location loc; - Bexpression *vex = be->var_expression(p3, loc); - Bexpression *c0 = be->convert_expression(bu8t, mkInt32Const(be, 0), loc); - Bexpression *eq = be->binary_expression(OPERATOR_EQEQ, vex, c0, loc); - - // call - Bexpression *fn = be->function_code_expression(func, loc); - std::vector args; - Bvariable *p0 = func->getNthParamVar(0); - args.push_back(be->var_expression(p0, loc)); - - Bvariable *p1 = func->getNthParamVar(1); - args.push_back(be->var_expression(p1, loc)); - - Bvariable *p2 = func->getNthParamVar(2); - args.push_back(be->var_expression(p2, loc)); - - Bvariable *p3x = func->getNthParamVar(3); - Bexpression *vex3 = be->var_expression(p3x, loc); - Bexpression *c1 = be->convert_expression(bu8t, mkInt32Const(be, 1), loc); - Bexpression *minus = be->binary_expression(OPERATOR_MINUS, vex3, c1, loc); - args.push_back(minus); - - Bvariable *p4 = func->getNthParamVar(4); - args.push_back(be->var_expression(p4, loc)); - - Bvariable *p5 = func->getNthParamVar(5); - args.push_back(be->var_expression(p5, loc)); - Bexpression *call = be->call_expression(func, fn, args, nullptr, h.loc()); - - // return y - std::vector rvals1; - rvals1.push_back(be->var_expression(p1, loc)); - Bstatement *rst1 = h.mkReturn(rvals1, FcnTestHarness::NoAppend); - - // return call - std::vector rvals2; - rvals2.push_back(call); - Bstatement *rst2 = h.mkReturn(rvals2, FcnTestHarness::NoAppend); - - DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT( - %p3.ld.0 = load i8, i8* %p3.addr, align 1 - %sub.0 = sub i8 %p3.ld.0, 1 - %p4.ld.0 = load i8, i8* %p4.addr, align 1 - %cast.1 = bitcast { float, float, i16, i16, i16 }* %p0.addr to { { float, float }, i48 }* - %field0.0 = getelementptr inbounds { { float, float }, i48 }, { { float, float }, i48 }* %cast.1, i32 0, i32 0 - %ld.1 = load { float, float }, { float, float }* %field0.0, align 4 - %field1.0 = getelementptr inbounds { { float, float }, i48 }, { { float, float }, i48 }* %cast.1, i32 0, i32 1 - %ld.2 = load i48, i48* %field1.0, align 8 - %cast.2 = bitcast { double, float, float }* %p1.addr to { double, { float, float } }* - %field0.1 = getelementptr inbounds { double, { float, float } }, { double, { float, float } }* %cast.2, i32 0, i32 0 - %ld.3 = load double, double* %field0.1, align 8 - %field1.1 = getelementptr inbounds { double, { float, float } }, { double, { float, float } }* %cast.2, i32 0, i32 1 - %ld.4 = load { float, float }, { float, float }* %field1.1, align 4 - %call.0 = call addrspace(0) { double, { float, float } } @foo(i8* nest undef, { float, float } %ld.1, i48 %ld.2, double %ld.3, { float, float } %ld.4, i8 zeroext %sub.0, i8 signext %p4.ld.0, { { float, float, i16, i16, i16 }, { double, float, float } }* byval({ { float, float, i16, i16, i16 }, { double, float, float } }) %p5) - %cast.3 = bitcast { double, float, float }* %sret.actual.0 to { double, { float, float } }* - store { double, { float, float } } %call.0, { double, { float, float } }* %cast.3, align 8 - %cast.4 = bitcast { double, float, float }* %sret.actual.0 to { double, { float, float } }* - %ld.5 = load { double, { float, float } }, { double, { float, float } }* %cast.4, align 8 - ret { double, { float, float } } %ld.5 - )RAW_RESULT"); - - bool isOK = h.expectStmt(rst2, exp); - EXPECT_TRUE(isOK && "Statement does not have expected contents"); - - // if statement - h.mkIf(eq, rst1, rst2); - - bool broken = h.finish(PreserveDebugInfo); - EXPECT_FALSE(broken && "Module failed to verify."); -} - TEST(BackendCABIOracleTests, PassAndReturnArraysAmd64) { FcnTestHarness h(gollvm::driver::CallingConvId::X86_64_SysV); Llvm_backend *be = h.be(); @@ -1085,53 +776,6 @@ TEST(BackendCABIOracleTests, PassAndReturnArraysArm64) { EXPECT_FALSE(broken && "Module failed to verify."); } -TEST(BackendCABIOracleTests, PassAndReturnArraysRV64) { - FcnTestHarness h(llvm::CallingConv::C); - Llvm_backend *be = h.be(); - - Btype *bf32t = be->float_type(32); - Btype *bf64t = be->float_type(64); - Btype *at2f = be->array_type(bf32t, mkInt64Const(be, int64_t(2))); - Btype *at3d = be->array_type(bf64t, mkInt64Const(be, int64_t(3))); - - // func foo(fp [2]float32) [3]float64 - BFunctionType *befty1 = mkFuncTyp(be, - L_PARM, at2f, - L_RES, at3d, - L_END); - Bfunction *func = h.mkFunction("foo", befty1); - - // foo(fp) - Location loc; - Bvariable *p0 = func->getNthParamVar(0); - Bexpression *vex = be->var_expression(p0, loc); - Bexpression *fn = be->function_code_expression(func, loc); - std::vector args; - args.push_back(vex); - Bexpression *call = be->call_expression(func, fn, args, nullptr, h.loc()); - - // return foo(fp) - std::vector rvals; - rvals.push_back(call); - h.mkReturn(rvals); - - DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT( - %cast.0 = bitcast [2 x float]* %p0.addr to { float, float }* - %ld.0 = load { float, float }, { float, float }* %cast.0, align 4 - call addrspace(0) void @foo([3 x double]* sret([3 x double]) "go_sret" %sret.actual.0, i8* nest undef, { float, float } %ld.0) - %cast.1 = bitcast [3 x double]* %sret.formal.0 to i8* - %cast.2 = bitcast [3 x double]* %sret.actual.0 to i8* - call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.1, i8* align 8 %cast.2, i64 24, i1 false) - ret void - )RAW_RESULT"); - - bool isOK = h.expectBlock(exp); - EXPECT_TRUE(isOK && "Block does not have expected contents"); - - bool broken = h.finish(PreserveDebugInfo); - EXPECT_FALSE(broken && "Module failed to verify."); -} - TEST_P(BackendCABIOracleTests, EmptyStructParamsAndReturns) { auto cc = GetParam(); FcnTestHarness h(cc); @@ -1348,75 +992,4 @@ TEST(BackendCABIOracleTests, PassAndReturnComplexArm64) { EXPECT_FALSE(broken && "Module failed to verify."); } -TEST(BackendCABIOracleTests, PassAndReturnComplexRV64) { - FcnTestHarness h(llvm::CallingConv::C); - Llvm_backend *be = h.be(); - - Btype *bc64t = be->complex_type(64); - Btype *bc128t = be->complex_type(128); - - // func foo(x complex64, y complex128) complex64 - BFunctionType *befty1 = mkFuncTyp(be, - L_PARM, bc64t, - L_PARM, bc128t, - L_RES, bc64t, - L_END); - Bfunction *func = h.mkFunction("foo", befty1); - - // z = foo(x, y) - Location loc; - Bvariable *x = func->getNthParamVar(0); - Bvariable *y = func->getNthParamVar(1); - Bexpression *xvex = be->var_expression(x, loc); - Bexpression *yvex = be->var_expression(y, loc); - Bexpression *fn1 = be->function_code_expression(func, loc); - std::vector args1 = {xvex, yvex}; - Bexpression *call1 = be->call_expression(func, fn1, args1, nullptr, h.loc()); - h.mkLocal("z", bc64t, call1); - - // Call with constant args - // foo(1+2i, 3+4i) - mpc_t mpc_val1, mpc_val2; - mpc_init2(mpc_val1, 256); - mpc_set_d_d(mpc_val1, 1.0, 2.0, GMP_RNDN); - mpc_init2(mpc_val2, 256); - mpc_set_d_d(mpc_val2, 3.0, 4.0, GMP_RNDN); - Bexpression *ccon1 = be->complex_constant_expression(bc64t, mpc_val1); - Bexpression *ccon2 = be->complex_constant_expression(bc128t, mpc_val2); - mpc_clear(mpc_val1); - mpc_clear(mpc_val2); - Bexpression *fn2 = be->function_code_expression(func, loc); - std::vector args2 = {ccon1, ccon2}; - Bexpression *call2 = be->call_expression(func, fn2, args2, nullptr, h.loc()); - - // return the call expr above - std::vector rvals = {call2}; - h.mkReturn(rvals); - - DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT( - %ld.0 = load { float, float }, { float, float }* %p0.addr, align 4 - %field0.0 = getelementptr inbounds { double, double }, { double, double }* %p1.addr, i32 0, i32 0 - %ld.1 = load double, double* %field0.0, align 8 - %field1.0 = getelementptr inbounds { double, double }, { double, double }* %p1.addr, i32 0, i32 1 - %ld.2 = load double, double* %field1.0, align 8 - %call.0 = call addrspace(0) { float, float } @foo(i8* nest undef, { float, float } %ld.0, double %ld.1, double %ld.2) - store { float, float } %call.0, { float, float }* %sret.actual.0, align 4 - %cast.3 = bitcast { float, float }* %z to i8* - %cast.4 = bitcast { float, float }* %sret.actual.0 to i8* - call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.3, i8* align 4 %cast.4, i64 8, i1 false) - %ld.3 = load { float, float }, { float, float }* @const.0, align 4 - %ld.4 = load double, double* getelementptr inbounds ({ double, double }, { double, double }* @const.1, i32 0, i32 0), align 8 - %ld.5 = load double, double* getelementptr inbounds ({ double, double }, { double, double }* @const.1, i32 0, i32 1), align 8 - %call.1 = call addrspace(0) { float, float } @foo(i8* nest undef, { float, float } %ld.3, double %ld.4, double %ld.5) - store { float, float } %call.1, { float, float }* %sret.actual.1, align 4 - %ld.6 = load { float, float }, { float, float }* %sret.actual.1, align 4 - ret { float, float } %ld.6 - )RAW_RESULT"); - - bool isOK = h.expectBlock(exp); - EXPECT_TRUE(isOK && "Block does not have expected contents"); - - bool broken = h.finish(PreserveDebugInfo); - EXPECT_FALSE(broken && "Module failed to verify."); -} } // namespace