forked from OSchip/llvm-project
[OpenMP] RISCV64 port
This is a port of libomp for the RISC-V 64-bit Linux target. We have tested this port on a HiFive Unleashed development board using a downstream LLVM that has support for the missing bits in upstream. As of now, all tests are passing, including OMPT. Patch by Ferran Pallarès! Differential Revision: https://reviews.llvm.org/D59880 llvm-svn: 367021
This commit is contained in:
parent
d668260f1a
commit
2488ae9df1
|
@ -133,7 +133,7 @@ Options for all Libraries
|
||||||
Options for ``libomp``
|
Options for ``libomp``
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
**LIBOMP_ARCH** = ``aarch64|arm|i386|mic|mips|mips64|ppc64|ppc64le|x86_64``
|
**LIBOMP_ARCH** = ``aarch64|arm|i386|mic|mips|mips64|ppc64|ppc64le|x86_64|riscv64``
|
||||||
The default value for this option is chosen based on probing the compiler for
|
The default value for this option is chosen based on probing the compiler for
|
||||||
architecture macros (e.g., is ``__x86_64__`` predefined by compiler?).
|
architecture macros (e.g., is ``__x86_64__`` predefined by compiler?).
|
||||||
|
|
||||||
|
@ -189,8 +189,8 @@ Optional Features
|
||||||
|
|
||||||
**LIBOMP_OMPT_SUPPORT** = ``ON|OFF``
|
**LIBOMP_OMPT_SUPPORT** = ``ON|OFF``
|
||||||
Include support for the OpenMP Tools Interface (OMPT).
|
Include support for the OpenMP Tools Interface (OMPT).
|
||||||
This option is supported and ``ON`` by default for x86, x86_64, AArch64, and
|
This option is supported and ``ON`` by default for x86, x86_64, AArch64,
|
||||||
PPC64 on Linux* and macOS*.
|
PPC64 and RISCV64 on Linux* and macOS*.
|
||||||
This option is ``OFF`` if this feature is not supported for the platform.
|
This option is ``OFF`` if this feature is not supported for the platform.
|
||||||
|
|
||||||
**LIBOMP_OMPT_OPTIONAL** = ``ON|OFF``
|
**LIBOMP_OMPT_OPTIONAL** = ``ON|OFF``
|
||||||
|
|
|
@ -30,7 +30,7 @@ if(${OPENMP_STANDALONE_BUILD})
|
||||||
# If adding a new architecture, take a look at cmake/LibompGetArchitecture.cmake
|
# If adding a new architecture, take a look at cmake/LibompGetArchitecture.cmake
|
||||||
libomp_get_architecture(LIBOMP_DETECTED_ARCH)
|
libomp_get_architecture(LIBOMP_DETECTED_ARCH)
|
||||||
set(LIBOMP_ARCH ${LIBOMP_DETECTED_ARCH} CACHE STRING
|
set(LIBOMP_ARCH ${LIBOMP_DETECTED_ARCH} CACHE STRING
|
||||||
"The architecture to build for (x86_64/i386/arm/ppc64/ppc64le/aarch64/mic/mips/mips64).")
|
"The architecture to build for (x86_64/i386/arm/ppc64/ppc64le/aarch64/mic/mips/mips64/riscv64).")
|
||||||
# Should assertions be enabled? They are on by default.
|
# Should assertions be enabled? They are on by default.
|
||||||
set(LIBOMP_ENABLE_ASSERTIONS TRUE CACHE BOOL
|
set(LIBOMP_ENABLE_ASSERTIONS TRUE CACHE BOOL
|
||||||
"enable assertions?")
|
"enable assertions?")
|
||||||
|
@ -58,13 +58,15 @@ else() # Part of LLVM build
|
||||||
set(LIBOMP_ARCH aarch64)
|
set(LIBOMP_ARCH aarch64)
|
||||||
elseif(LIBOMP_NATIVE_ARCH MATCHES "arm")
|
elseif(LIBOMP_NATIVE_ARCH MATCHES "arm")
|
||||||
set(LIBOMP_ARCH arm)
|
set(LIBOMP_ARCH arm)
|
||||||
|
elseif(LIBOMP_NATIVE_ARCH MATCHES "riscv64")
|
||||||
|
set(LIBOMP_ARCH riscv64)
|
||||||
else()
|
else()
|
||||||
# last ditch effort
|
# last ditch effort
|
||||||
libomp_get_architecture(LIBOMP_ARCH)
|
libomp_get_architecture(LIBOMP_ARCH)
|
||||||
endif ()
|
endif ()
|
||||||
set(LIBOMP_ENABLE_ASSERTIONS ${LLVM_ENABLE_ASSERTIONS})
|
set(LIBOMP_ENABLE_ASSERTIONS ${LLVM_ENABLE_ASSERTIONS})
|
||||||
endif()
|
endif()
|
||||||
libomp_check_variable(LIBOMP_ARCH 32e x86_64 32 i386 arm ppc64 ppc64le aarch64 mic mips mips64)
|
libomp_check_variable(LIBOMP_ARCH 32e x86_64 32 i386 arm ppc64 ppc64le aarch64 mic mips mips64 riscv64)
|
||||||
|
|
||||||
set(LIBOMP_LIB_TYPE normal CACHE STRING
|
set(LIBOMP_LIB_TYPE normal CACHE STRING
|
||||||
"Performance,Profiling,Stubs library (normal/profile/stubs)")
|
"Performance,Profiling,Stubs library (normal/profile/stubs)")
|
||||||
|
@ -142,6 +144,7 @@ set(PPC64 FALSE)
|
||||||
set(MIC FALSE)
|
set(MIC FALSE)
|
||||||
set(MIPS64 FALSE)
|
set(MIPS64 FALSE)
|
||||||
set(MIPS FALSE)
|
set(MIPS FALSE)
|
||||||
|
set(RISCV64 FALSE)
|
||||||
if("${LIBOMP_ARCH}" STREQUAL "i386" OR "${LIBOMP_ARCH}" STREQUAL "32") # IA-32 architecture
|
if("${LIBOMP_ARCH}" STREQUAL "i386" OR "${LIBOMP_ARCH}" STREQUAL "32") # IA-32 architecture
|
||||||
set(IA32 TRUE)
|
set(IA32 TRUE)
|
||||||
elseif("${LIBOMP_ARCH}" STREQUAL "x86_64" OR "${LIBOMP_ARCH}" STREQUAL "32e") # Intel(R) 64 architecture
|
elseif("${LIBOMP_ARCH}" STREQUAL "x86_64" OR "${LIBOMP_ARCH}" STREQUAL "32e") # Intel(R) 64 architecture
|
||||||
|
@ -162,6 +165,8 @@ elseif("${LIBOMP_ARCH}" STREQUAL "mips") # MIPS architecture
|
||||||
set(MIPS TRUE)
|
set(MIPS TRUE)
|
||||||
elseif("${LIBOMP_ARCH}" STREQUAL "mips64") # MIPS64 architecture
|
elseif("${LIBOMP_ARCH}" STREQUAL "mips64") # MIPS64 architecture
|
||||||
set(MIPS64 TRUE)
|
set(MIPS64 TRUE)
|
||||||
|
elseif("${LIBOMP_ARCH}" STREQUAL "riscv64") # RISCV64 architecture
|
||||||
|
set(RISCV64 TRUE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Set some flags based on build_type
|
# Set some flags based on build_type
|
||||||
|
|
|
@ -53,6 +53,7 @@ Architectures Supported
|
||||||
* IBM(R) Power architecture (big endian)
|
* IBM(R) Power architecture (big endian)
|
||||||
* IBM(R) Power architecture (little endian)
|
* IBM(R) Power architecture (little endian)
|
||||||
* MIPS and MIPS64 architecture
|
* MIPS and MIPS64 architecture
|
||||||
|
* RISCV64 architecture
|
||||||
|
|
||||||
Supported RTL Build Configurations
|
Supported RTL Build Configurations
|
||||||
==================================
|
==================================
|
||||||
|
|
|
@ -45,6 +45,8 @@ function(libomp_get_architecture return_arch)
|
||||||
#error ARCHITECTURE=mips64
|
#error ARCHITECTURE=mips64
|
||||||
#elif defined(__mips__) && !defined(__mips64)
|
#elif defined(__mips__) && !defined(__mips64)
|
||||||
#error ARCHITECTURE=mips
|
#error ARCHITECTURE=mips
|
||||||
|
#elif defined(__riscv) && __riscv_xlen == 64
|
||||||
|
#error ARCHITECTURE=riscv64
|
||||||
#else
|
#else
|
||||||
#error ARCHITECTURE=UnknownArchitecture
|
#error ARCHITECTURE=UnknownArchitecture
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -211,6 +211,9 @@ else()
|
||||||
elseif(${MIPS} OR ${MIPS64})
|
elseif(${MIPS} OR ${MIPS64})
|
||||||
libomp_append(libomp_expected_library_deps libc.so.6)
|
libomp_append(libomp_expected_library_deps libc.so.6)
|
||||||
libomp_append(libomp_expected_library_deps ld.so.1)
|
libomp_append(libomp_expected_library_deps ld.so.1)
|
||||||
|
elseif(${RISCV64})
|
||||||
|
libomp_append(libomp_expected_library_deps libc.so.6)
|
||||||
|
libomp_append(libomp_expected_library_deps ld.so.1)
|
||||||
endif()
|
endif()
|
||||||
libomp_append(libomp_expected_library_deps libpthread.so.0 IF_FALSE STUBS_LIBRARY)
|
libomp_append(libomp_expected_library_deps libpthread.so.0 IF_FALSE STUBS_LIBRARY)
|
||||||
libomp_append(libomp_expected_library_deps libhwloc.so.5 LIBOMP_USE_HWLOC)
|
libomp_append(libomp_expected_library_deps libhwloc.so.5 LIBOMP_USE_HWLOC)
|
||||||
|
|
|
@ -105,6 +105,8 @@ function(libomp_get_legal_arch return_arch_string)
|
||||||
set(${return_arch_string} "MIPS" PARENT_SCOPE)
|
set(${return_arch_string} "MIPS" PARENT_SCOPE)
|
||||||
elseif(${MIPS64})
|
elseif(${MIPS64})
|
||||||
set(${return_arch_string} "MIPS64" PARENT_SCOPE)
|
set(${return_arch_string} "MIPS64" PARENT_SCOPE)
|
||||||
|
elseif(${RISCV64})
|
||||||
|
set(${return_arch_string} "RISCV64" PARENT_SCOPE)
|
||||||
else()
|
else()
|
||||||
set(${return_arch_string} "${LIBOMP_ARCH}" PARENT_SCOPE)
|
set(${return_arch_string} "${LIBOMP_ARCH}" PARENT_SCOPE)
|
||||||
libomp_warning_say("libomp_get_legal_arch(): Warning: Unknown architecture: Using ${LIBOMP_ARCH}")
|
libomp_warning_say("libomp_get_legal_arch(): Warning: Unknown architecture: Using ${LIBOMP_ARCH}")
|
||||||
|
|
|
@ -246,7 +246,8 @@ else()
|
||||||
# (LIBOMP_ARCH STREQUAL arm) OR
|
# (LIBOMP_ARCH STREQUAL arm) OR
|
||||||
(LIBOMP_ARCH STREQUAL aarch64) OR
|
(LIBOMP_ARCH STREQUAL aarch64) OR
|
||||||
(LIBOMP_ARCH STREQUAL ppc64le) OR
|
(LIBOMP_ARCH STREQUAL ppc64le) OR
|
||||||
(LIBOMP_ARCH STREQUAL ppc64))
|
(LIBOMP_ARCH STREQUAL ppc64) OR
|
||||||
|
(LIBOMP_ARCH STREQUAL riscv64))
|
||||||
AND # OS supported?
|
AND # OS supported?
|
||||||
((WIN32 AND LIBOMP_HAVE_PSAPI) OR APPLE OR (NOT WIN32 AND LIBOMP_HAVE_WEAK_ATTRIBUTE)))
|
((WIN32 AND LIBOMP_HAVE_PSAPI) OR APPLE OR (NOT WIN32 AND LIBOMP_HAVE_WEAK_ATTRIBUTE)))
|
||||||
set(LIBOMP_HAVE_OMPT_SUPPORT TRUE)
|
set(LIBOMP_HAVE_OMPT_SUPPORT TRUE)
|
||||||
|
|
|
@ -676,7 +676,8 @@ void __kmpc_flush(ident_t *loc) {
|
||||||
#endif // KMP_COMPILER_ICC
|
#endif // KMP_COMPILER_ICC
|
||||||
}
|
}
|
||||||
#endif // KMP_MIC
|
#endif // KMP_MIC
|
||||||
#elif (KMP_ARCH_ARM || KMP_ARCH_AARCH64 || KMP_ARCH_MIPS || KMP_ARCH_MIPS64)
|
#elif (KMP_ARCH_ARM || KMP_ARCH_AARCH64 || KMP_ARCH_MIPS || KMP_ARCH_MIPS64 || \
|
||||||
|
KMP_ARCH_RISCV64)
|
||||||
// Nothing to see here move along
|
// Nothing to see here move along
|
||||||
#elif KMP_ARCH_PPC64
|
#elif KMP_ARCH_PPC64
|
||||||
// Nothing needed here (we have a real MB above).
|
// Nothing needed here (we have a real MB above).
|
||||||
|
|
|
@ -165,7 +165,8 @@ typedef unsigned long long kmp_uint64;
|
||||||
|
|
||||||
#if KMP_ARCH_X86 || KMP_ARCH_ARM || KMP_ARCH_MIPS
|
#if KMP_ARCH_X86 || KMP_ARCH_ARM || KMP_ARCH_MIPS
|
||||||
#define KMP_SIZE_T_SPEC KMP_UINT32_SPEC
|
#define KMP_SIZE_T_SPEC KMP_UINT32_SPEC
|
||||||
#elif KMP_ARCH_X86_64 || KMP_ARCH_PPC64 || KMP_ARCH_AARCH64 || KMP_ARCH_MIPS64
|
#elif KMP_ARCH_X86_64 || KMP_ARCH_PPC64 || KMP_ARCH_AARCH64 || \
|
||||||
|
KMP_ARCH_MIPS64 || KMP_ARCH_RISCV64
|
||||||
#define KMP_SIZE_T_SPEC KMP_UINT64_SPEC
|
#define KMP_SIZE_T_SPEC KMP_UINT64_SPEC
|
||||||
#else
|
#else
|
||||||
#error "Can't determine size_t printf format specifier."
|
#error "Can't determine size_t printf format specifier."
|
||||||
|
@ -840,7 +841,7 @@ extern kmp_real64 __kmp_xchg_real64(volatile kmp_real64 *p, kmp_real64 v);
|
||||||
#endif /* KMP_OS_WINDOWS */
|
#endif /* KMP_OS_WINDOWS */
|
||||||
|
|
||||||
#if KMP_ARCH_PPC64 || KMP_ARCH_ARM || KMP_ARCH_AARCH64 || KMP_ARCH_MIPS || \
|
#if KMP_ARCH_PPC64 || KMP_ARCH_ARM || KMP_ARCH_AARCH64 || KMP_ARCH_MIPS || \
|
||||||
KMP_ARCH_MIPS64
|
KMP_ARCH_MIPS64 || KMP_ARCH_RISCV64
|
||||||
#define KMP_MB() __sync_synchronize()
|
#define KMP_MB() __sync_synchronize()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -98,6 +98,7 @@
|
||||||
#define KMP_ARCH_PPC64 (KMP_ARCH_PPC64_LE || KMP_ARCH_PPC64_BE)
|
#define KMP_ARCH_PPC64 (KMP_ARCH_PPC64_LE || KMP_ARCH_PPC64_BE)
|
||||||
#define KMP_ARCH_MIPS 0
|
#define KMP_ARCH_MIPS 0
|
||||||
#define KMP_ARCH_MIPS64 0
|
#define KMP_ARCH_MIPS64 0
|
||||||
|
#define KMP_ARCH_RISCV64 0
|
||||||
|
|
||||||
#if KMP_OS_WINDOWS
|
#if KMP_OS_WINDOWS
|
||||||
#if defined(_M_AMD64) || defined(__x86_64)
|
#if defined(_M_AMD64) || defined(__x86_64)
|
||||||
|
@ -135,6 +136,9 @@
|
||||||
#undef KMP_ARCH_MIPS
|
#undef KMP_ARCH_MIPS
|
||||||
#define KMP_ARCH_MIPS 1
|
#define KMP_ARCH_MIPS 1
|
||||||
#endif
|
#endif
|
||||||
|
#elif defined __riscv && __riscv_xlen == 64
|
||||||
|
#undef KMP_ARCH_RISCV64
|
||||||
|
#define KMP_ARCH_RISCV64 1
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -199,7 +203,7 @@
|
||||||
// TODO: Fixme - This is clever, but really fugly
|
// TODO: Fixme - This is clever, but really fugly
|
||||||
#if (1 != \
|
#if (1 != \
|
||||||
KMP_ARCH_X86 + KMP_ARCH_X86_64 + KMP_ARCH_ARM + KMP_ARCH_PPC64 + \
|
KMP_ARCH_X86 + KMP_ARCH_X86_64 + KMP_ARCH_ARM + KMP_ARCH_PPC64 + \
|
||||||
KMP_ARCH_AARCH64 + KMP_ARCH_MIPS + KMP_ARCH_MIPS64)
|
KMP_ARCH_AARCH64 + KMP_ARCH_MIPS + KMP_ARCH_MIPS64 + KMP_ARCH_RISCV64)
|
||||||
#error Unknown or unsupported architecture
|
#error Unknown or unsupported architecture
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -8023,7 +8023,8 @@ __kmp_determine_reduction_method(
|
||||||
|
|
||||||
int atomic_available = FAST_REDUCTION_ATOMIC_METHOD_GENERATED;
|
int atomic_available = FAST_REDUCTION_ATOMIC_METHOD_GENERATED;
|
||||||
|
|
||||||
#if KMP_ARCH_X86_64 || KMP_ARCH_PPC64 || KMP_ARCH_AARCH64 || KMP_ARCH_MIPS64
|
#if KMP_ARCH_X86_64 || KMP_ARCH_PPC64 || KMP_ARCH_AARCH64 || \
|
||||||
|
KMP_ARCH_MIPS64 || KMP_ARCH_RISCV64
|
||||||
|
|
||||||
#if KMP_OS_LINUX || KMP_OS_DRAGONFLY || KMP_OS_FREEBSD || KMP_OS_NETBSD || \
|
#if KMP_OS_LINUX || KMP_OS_DRAGONFLY || KMP_OS_FREEBSD || KMP_OS_NETBSD || \
|
||||||
KMP_OS_OPENBSD || KMP_OS_WINDOWS || KMP_OS_DARWIN || KMP_OS_HURD
|
KMP_OS_OPENBSD || KMP_OS_WINDOWS || KMP_OS_DARWIN || KMP_OS_HURD
|
||||||
|
|
|
@ -161,6 +161,10 @@
|
||||||
# define ITT_ARCH_MIPS64 6
|
# define ITT_ARCH_MIPS64 6
|
||||||
#endif /* ITT_ARCH_MIPS64 */
|
#endif /* ITT_ARCH_MIPS64 */
|
||||||
|
|
||||||
|
#ifndef ITT_ARCH_RISCV64
|
||||||
|
# define ITT_ARCH_RISCV64 7
|
||||||
|
#endif /* ITT_ARCH_RISCV64 */
|
||||||
|
|
||||||
#ifndef ITT_ARCH
|
#ifndef ITT_ARCH
|
||||||
# if defined _M_IX86 || defined __i386__
|
# if defined _M_IX86 || defined __i386__
|
||||||
# define ITT_ARCH ITT_ARCH_IA32
|
# define ITT_ARCH ITT_ARCH_IA32
|
||||||
|
@ -178,6 +182,8 @@
|
||||||
# define ITT_ARCH ITT_ARCH_MIPS
|
# define ITT_ARCH ITT_ARCH_MIPS
|
||||||
# elif defined __mips__ && defined __mips64
|
# elif defined __mips__ && defined __mips64
|
||||||
# define ITT_ARCH ITT_ARCH_MIPS64
|
# define ITT_ARCH ITT_ARCH_MIPS64
|
||||||
|
# elif defined __riscv && __riscv_xlen == 64
|
||||||
|
# define ITT_ARCH ITT_ARCH_RISCV64
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -330,7 +336,9 @@ ITT_INLINE long __TBB_machine_fetchadd4(volatile void* ptr, long addend)
|
||||||
: "memory");
|
: "memory");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#elif ITT_ARCH==ITT_ARCH_ARM || ITT_ARCH==ITT_ARCH_PPC64 || ITT_ARCH==ITT_ARCH_AARCH64 || ITT_ARCH==ITT_ARCH_MIPS || ITT_ARCH==ITT_ARCH_MIPS64
|
#elif ITT_ARCH == ITT_ARCH_ARM || ITT_ARCH == ITT_ARCH_PPC64 || \
|
||||||
|
ITT_ARCH == ITT_ARCH_AARCH64 || ITT_ARCH == ITT_ARCH_MIPS || \
|
||||||
|
ITT_ARCH == ITT_ARCH_MIPS64 || ITT_ARCH == ITT_ARCH_RISCV64
|
||||||
#define __TBB_machine_fetchadd4(addr, val) __sync_fetch_and_add(addr, val)
|
#define __TBB_machine_fetchadd4(addr, val) __sync_fetch_and_add(addr, val)
|
||||||
#endif /* ITT_ARCH==ITT_ARCH_IA64 */
|
#endif /* ITT_ARCH==ITT_ARCH_IA64 */
|
||||||
#ifndef ITT_SIMPLE_INIT
|
#ifndef ITT_SIMPLE_INIT
|
||||||
|
|
|
@ -1563,6 +1563,173 @@ __kmp_invoke_microtask:
|
||||||
|
|
||||||
#endif /* KMP_ARCH_PPC64 */
|
#endif /* KMP_ARCH_PPC64 */
|
||||||
|
|
||||||
|
#if KMP_ARCH_RISCV64
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// typedef void (*microtask_t)(int *gtid, int *tid, ...);
|
||||||
|
//
|
||||||
|
// int __kmp_invoke_microtask(microtask_t pkfn, int gtid, int tid, int argc,
|
||||||
|
// void *p_argv[]
|
||||||
|
// #if OMPT_SUPPORT
|
||||||
|
// ,
|
||||||
|
// void **exit_frame_ptr
|
||||||
|
// #endif
|
||||||
|
// ) {
|
||||||
|
// #if OMPT_SUPPORT
|
||||||
|
// *exit_frame_ptr = OMPT_GET_FRAME_ADDRESS(0);
|
||||||
|
// #endif
|
||||||
|
//
|
||||||
|
// (*pkfn)(>id, &tid, argv[0], ...);
|
||||||
|
//
|
||||||
|
// return 1;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// a0: pkfn
|
||||||
|
// a1: gtid
|
||||||
|
// a2: tid
|
||||||
|
// a3: argc
|
||||||
|
// a4: p_argv
|
||||||
|
// a5: exit_frame_ptr
|
||||||
|
//
|
||||||
|
// Locals:
|
||||||
|
// __gtid: gtid param pushed on stack so can pass >id to pkfn
|
||||||
|
// __tid: tid param pushed on stack so can pass &tid to pkfn
|
||||||
|
//
|
||||||
|
// Temp. registers:
|
||||||
|
//
|
||||||
|
// t0: used to calculate the dynamic stack size / used to hold pkfn address
|
||||||
|
// t1: used as temporary for stack placement calculation
|
||||||
|
// t2: used as temporary for stack arguments
|
||||||
|
// t3: used as temporary for number of remaining pkfn parms
|
||||||
|
// t4: used to traverse p_argv array
|
||||||
|
//
|
||||||
|
// return: a0 (always 1/TRUE)
|
||||||
|
//
|
||||||
|
|
||||||
|
__gtid = -20
|
||||||
|
__tid = -24
|
||||||
|
|
||||||
|
// -- Begin __kmp_invoke_microtask
|
||||||
|
// mark_begin;
|
||||||
|
.text
|
||||||
|
.globl __kmp_invoke_microtask
|
||||||
|
.p2align 1
|
||||||
|
.type __kmp_invoke_microtask,@function
|
||||||
|
__kmp_invoke_microtask:
|
||||||
|
.cfi_startproc
|
||||||
|
|
||||||
|
// First, save ra and fp
|
||||||
|
addi sp, sp, -16
|
||||||
|
sd ra, 8(sp)
|
||||||
|
sd fp, 0(sp)
|
||||||
|
addi fp, sp, 16
|
||||||
|
.cfi_def_cfa fp, 0
|
||||||
|
.cfi_offset ra, -8
|
||||||
|
.cfi_offset fp, -16
|
||||||
|
|
||||||
|
// Compute the dynamic stack size:
|
||||||
|
//
|
||||||
|
// - We need 8 bytes for storing 'gtid' and 'tid', so we can pass them by
|
||||||
|
// reference
|
||||||
|
// - We need 8 bytes for each argument that cannot be passed to the 'pkfn'
|
||||||
|
// function by register. Given that we have 8 of such registers (a[0-7])
|
||||||
|
// and two + 'argc' arguments (consider >id and &tid), we need to
|
||||||
|
// reserve max(0, argc - 6)*8 extra bytes
|
||||||
|
//
|
||||||
|
// The total number of bytes is then max(0, argc - 6)*8 + 8
|
||||||
|
|
||||||
|
// Compute max(0, argc - 6) using the following bithack:
|
||||||
|
// max(0, x) = x - (x & (x >> 31)), where x := argc - 6
|
||||||
|
// Source: http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax
|
||||||
|
addi t0, a3, -6
|
||||||
|
srai t1, t0, 31
|
||||||
|
and t1, t0, t1
|
||||||
|
sub t0, t0, t1
|
||||||
|
|
||||||
|
addi t0, t0, 1
|
||||||
|
|
||||||
|
slli t0, t0, 3
|
||||||
|
sub sp, sp, t0
|
||||||
|
|
||||||
|
// Align the stack to 16 bytes
|
||||||
|
andi sp, sp, -16
|
||||||
|
|
||||||
|
mv t0, a0
|
||||||
|
mv t3, a3
|
||||||
|
mv t4, a4
|
||||||
|
|
||||||
|
#if OMPT_SUPPORT
|
||||||
|
// Save frame pointer into exit_frame
|
||||||
|
sd fp, 0(a5)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Prepare arguments for the pkfn function (first 8 using a0-a7 registers)
|
||||||
|
|
||||||
|
sw a1, __gtid(fp)
|
||||||
|
sw a2, __tid(fp)
|
||||||
|
|
||||||
|
addi a0, fp, __gtid
|
||||||
|
addi a1, fp, __tid
|
||||||
|
|
||||||
|
beqz t3, .L_kmp_3
|
||||||
|
ld a2, 0(t4)
|
||||||
|
|
||||||
|
addi t3, t3, -1
|
||||||
|
beqz t3, .L_kmp_3
|
||||||
|
ld a3, 8(t4)
|
||||||
|
|
||||||
|
addi t3, t3, -1
|
||||||
|
beqz t3, .L_kmp_3
|
||||||
|
ld a4, 16(t4)
|
||||||
|
|
||||||
|
addi t3, t3, -1
|
||||||
|
beqz t3, .L_kmp_3
|
||||||
|
ld a5, 24(t4)
|
||||||
|
|
||||||
|
addi t3, t3, -1
|
||||||
|
beqz t3, .L_kmp_3
|
||||||
|
ld a6, 32(t4)
|
||||||
|
|
||||||
|
addi t3, t3, -1
|
||||||
|
beqz t3, .L_kmp_3
|
||||||
|
ld a7, 40(t4)
|
||||||
|
|
||||||
|
// Prepare any additional argument passed through the stack
|
||||||
|
addi t4, t4, 48
|
||||||
|
mv t1, sp
|
||||||
|
j .L_kmp_2
|
||||||
|
.L_kmp_1:
|
||||||
|
ld t2, 0(t4)
|
||||||
|
sd t2, 0(t1)
|
||||||
|
addi t4, t4, 8
|
||||||
|
addi t1, t1, 8
|
||||||
|
.L_kmp_2:
|
||||||
|
addi t3, t3, -1
|
||||||
|
bnez t3, .L_kmp_1
|
||||||
|
|
||||||
|
.L_kmp_3:
|
||||||
|
// Call pkfn function
|
||||||
|
jalr t0
|
||||||
|
|
||||||
|
// Restore stack and return
|
||||||
|
|
||||||
|
addi a0, zero, 1
|
||||||
|
|
||||||
|
addi sp, fp, -16
|
||||||
|
ld fp, 0(sp)
|
||||||
|
ld ra, 8(sp)
|
||||||
|
addi sp, sp, 16
|
||||||
|
ret
|
||||||
|
.Lfunc_end0:
|
||||||
|
.size __kmp_invoke_microtask, .Lfunc_end0-__kmp_invoke_microtask
|
||||||
|
.cfi_endproc
|
||||||
|
|
||||||
|
// -- End __kmp_invoke_microtask
|
||||||
|
|
||||||
|
#endif /* KMP_ARCH_RISCV64 */
|
||||||
|
|
||||||
#if KMP_ARCH_ARM || KMP_ARCH_MIPS
|
#if KMP_ARCH_ARM || KMP_ARCH_MIPS
|
||||||
.data
|
.data
|
||||||
.comm .gomp_critical_user_,32,8
|
.comm .gomp_critical_user_,32,8
|
||||||
|
@ -1574,7 +1741,7 @@ __kmp_unnamed_critical_addr:
|
||||||
.size __kmp_unnamed_critical_addr,4
|
.size __kmp_unnamed_critical_addr,4
|
||||||
#endif /* KMP_ARCH_ARM */
|
#endif /* KMP_ARCH_ARM */
|
||||||
|
|
||||||
#if KMP_ARCH_PPC64 || KMP_ARCH_AARCH64 || KMP_ARCH_MIPS64
|
#if KMP_ARCH_PPC64 || KMP_ARCH_AARCH64 || KMP_ARCH_MIPS64 || KMP_ARCH_RISCV64
|
||||||
.data
|
.data
|
||||||
.comm .gomp_critical_user_,32,8
|
.comm .gomp_critical_user_,32,8
|
||||||
.data
|
.data
|
||||||
|
@ -1583,7 +1750,8 @@ __kmp_unnamed_critical_addr:
|
||||||
__kmp_unnamed_critical_addr:
|
__kmp_unnamed_critical_addr:
|
||||||
.8byte .gomp_critical_user_
|
.8byte .gomp_critical_user_
|
||||||
.size __kmp_unnamed_critical_addr,8
|
.size __kmp_unnamed_critical_addr,8
|
||||||
#endif /* KMP_ARCH_PPC64 || KMP_ARCH_AARCH64 */
|
#endif /* KMP_ARCH_PPC64 || KMP_ARCH_AARCH64 || KMP_ARCH_MIPS64 ||
|
||||||
|
KMP_ARCH_RISCV64 */
|
||||||
|
|
||||||
#if KMP_OS_LINUX
|
#if KMP_OS_LINUX
|
||||||
# if KMP_ARCH_ARM
|
# if KMP_ARCH_ARM
|
||||||
|
|
|
@ -2331,7 +2331,8 @@ finish: // Clean up and exit.
|
||||||
#endif // USE_LOAD_BALANCE
|
#endif // USE_LOAD_BALANCE
|
||||||
|
|
||||||
#if !(KMP_ARCH_X86 || KMP_ARCH_X86_64 || KMP_MIC || \
|
#if !(KMP_ARCH_X86 || KMP_ARCH_X86_64 || KMP_MIC || \
|
||||||
((KMP_OS_LINUX || KMP_OS_DARWIN) && KMP_ARCH_AARCH64) || KMP_ARCH_PPC64)
|
((KMP_OS_LINUX || KMP_OS_DARWIN) && KMP_ARCH_AARCH64) || \
|
||||||
|
KMP_ARCH_PPC64 || KMP_ARCH_RISCV64)
|
||||||
|
|
||||||
// we really only need the case with 1 argument, because CLANG always build
|
// we really only need the case with 1 argument, because CLANG always build
|
||||||
// a struct of pointers to shared variables referenced in the outlined function
|
// a struct of pointers to shared variables referenced in the outlined function
|
||||||
|
|
|
@ -168,6 +168,26 @@ ompt_label_##id:
|
||||||
#define print_possible_return_addresses(addr) \
|
#define print_possible_return_addresses(addr) \
|
||||||
printf("%" PRIu64 ": current_address=%p or %p\n", ompt_get_thread_data()->value, \
|
printf("%" PRIu64 ": current_address=%p or %p\n", ompt_get_thread_data()->value, \
|
||||||
((char *)addr) - 4, ((char *)addr) - 8)
|
((char *)addr) - 4, ((char *)addr) - 8)
|
||||||
|
#elif KMP_ARCH_RISCV64
|
||||||
|
#if __riscv_compressed
|
||||||
|
// On RV64GC the C.NOP instruction is 2 byte long. In addition, the compiler
|
||||||
|
// inserts a J instruction (targeting the successor basic block), which
|
||||||
|
// accounts for another 4 bytes. Finally, an additional J instruction may
|
||||||
|
// appear (adding 4 more bytes) when the C.NOP is referenced elsewhere (ie.
|
||||||
|
// another branch).
|
||||||
|
#define print_possible_return_addresses(addr) \
|
||||||
|
printf("%" PRIu64 ": current_address=%p or %p\n", \
|
||||||
|
ompt_get_thread_data()->value, ((char *)addr) - 6, ((char *)addr) - 10)
|
||||||
|
#else
|
||||||
|
// On RV64G the NOP instruction is 4 byte long. In addition, the compiler
|
||||||
|
// inserts a J instruction (targeting the successor basic block), which
|
||||||
|
// accounts for another 4 bytes. Finally, an additional J instruction may
|
||||||
|
// appear (adding 4 more bytes) when the NOP is referenced elsewhere (ie.
|
||||||
|
// another branch).
|
||||||
|
#define print_possible_return_addresses(addr) \
|
||||||
|
printf("%" PRIu64 ": current_address=%p or %p\n", \
|
||||||
|
ompt_get_thread_data()->value, ((char *)addr) - 8, ((char *)addr) - 12)
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
#error Unsupported target architecture, cannot determine address offset!
|
#error Unsupported target architecture, cannot determine address offset!
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -61,6 +61,8 @@ sub canon_arch($) {
|
||||||
$arch = "mips64";
|
$arch = "mips64";
|
||||||
} elsif ( $arch =~ m{\Amips} ) {
|
} elsif ( $arch =~ m{\Amips} ) {
|
||||||
$arch = "mips";
|
$arch = "mips";
|
||||||
|
} elsif ( $arch =~ m{\Ariscv64} ) {
|
||||||
|
$arch = "riscv64";
|
||||||
} else {
|
} else {
|
||||||
$arch = undef;
|
$arch = undef;
|
||||||
}; # if
|
}; # if
|
||||||
|
@ -94,6 +96,7 @@ sub canon_mic_arch($) {
|
||||||
"mic" => "Intel(R) Many Integrated Core Architecture",
|
"mic" => "Intel(R) Many Integrated Core Architecture",
|
||||||
"mips" => "MIPS",
|
"mips" => "MIPS",
|
||||||
"mips64" => "MIPS64",
|
"mips64" => "MIPS64",
|
||||||
|
"riscv64" => "RISC-V (64-bit)",
|
||||||
);
|
);
|
||||||
|
|
||||||
sub legal_arch($) {
|
sub legal_arch($) {
|
||||||
|
@ -220,6 +223,8 @@ sub target_options() {
|
||||||
$_host_arch = "mips64";
|
$_host_arch = "mips64";
|
||||||
} elsif ( $hardware_platform eq "mips" ) {
|
} elsif ( $hardware_platform eq "mips" ) {
|
||||||
$_host_arch = "mips";
|
$_host_arch = "mips";
|
||||||
|
} elsif ( $hardware_platform eq "riscv64" ) {
|
||||||
|
$_host_arch = "riscv64";
|
||||||
} else {
|
} else {
|
||||||
die "Unsupported host hardware platform: \"$hardware_platform\"; stopped";
|
die "Unsupported host hardware platform: \"$hardware_platform\"; stopped";
|
||||||
}; # if
|
}; # if
|
||||||
|
@ -409,7 +414,7 @@ the script assumes host architecture is target one.
|
||||||
|
|
||||||
Input string is an architecture name to canonize. The function recognizes many variants, for example:
|
Input string is an architecture name to canonize. The function recognizes many variants, for example:
|
||||||
C<32e>, C<Intel64>, C<Intel(R) 64>, etc. Returned string is a canononized architecture name,
|
C<32e>, C<Intel64>, C<Intel(R) 64>, etc. Returned string is a canononized architecture name,
|
||||||
one of: C<32>, C<32e>, C<64>, C<arm>, C<ppc64le>, C<ppc64>, C<mic>, C<mips>, C<mips64>, or C<undef> is input string is not recognized.
|
one of: C<32>, C<32e>, C<64>, C<arm>, C<ppc64le>, C<ppc64>, C<mic>, C<mips>, C<mips64>, C<riscv64> or C<undef> is input string is not recognized.
|
||||||
|
|
||||||
=item B<legal_arch( $arch )>
|
=item B<legal_arch( $arch )>
|
||||||
|
|
||||||
|
|
|
@ -156,6 +156,8 @@ if ( 0 ) {
|
||||||
$values{ hardware_platform } = "mips64";
|
$values{ hardware_platform } = "mips64";
|
||||||
} elsif ( $values{ machine } =~ m{\Amips\z} ) {
|
} elsif ( $values{ machine } =~ m{\Amips\z} ) {
|
||||||
$values{ hardware_platform } = "mips";
|
$values{ hardware_platform } = "mips";
|
||||||
|
} elsif ( $values{ machine } =~ m{\Ariscv64\z} ) {
|
||||||
|
$values{ hardware_platform } = "riscv64";
|
||||||
} else {
|
} else {
|
||||||
die "Unsupported machine (\"$values{ machine }\") returned by POSIX::uname(); stopped";
|
die "Unsupported machine (\"$values{ machine }\") returned by POSIX::uname(); stopped";
|
||||||
}; # if
|
}; # if
|
||||||
|
|
|
@ -53,6 +53,7 @@ Architectures Supported
|
||||||
* IBM(R) Power architecture (big endian)
|
* IBM(R) Power architecture (big endian)
|
||||||
* IBM(R) Power architecture (little endian)
|
* IBM(R) Power architecture (little endian)
|
||||||
* MIPS and MIPS64 architectures
|
* MIPS and MIPS64 architectures
|
||||||
|
* RISC-V 64 bit architecture
|
||||||
|
|
||||||
Supported RTL Build Configurations
|
Supported RTL Build Configurations
|
||||||
==================================
|
==================================
|
||||||
|
|
|
@ -134,6 +134,7 @@
|
||||||
the Intel compiler.
|
the Intel compiler.
|
||||||
</li>
|
</li>
|
||||||
<li>MIPS and MIPS64</li>
|
<li>MIPS and MIPS64</li>
|
||||||
|
<li>RISC-V 64-bit</li>
|
||||||
</ul>
|
</ul>
|
||||||
Ports to other architectures and operating systems are welcome.
|
Ports to other architectures and operating systems are welcome.
|
||||||
</p>
|
</p>
|
||||||
|
|
Loading…
Reference in New Issue