[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:
Jonas Hahnfeld 2019-07-25 14:36:20 +00:00
parent d668260f1a
commit 2488ae9df1
19 changed files with 243 additions and 16 deletions

View File

@ -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``

View File

@ -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

View File

@ -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
================================== ==================================

View File

@ -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

View File

@ -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)

View File

@ -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}")

View File

@ -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)

View File

@ -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).

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)(&gtid, &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 &gtid 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 &gtid 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

View File

@ -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

View File

@ -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

View File

@ -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 )>

View File

@ -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

View File

@ -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
================================== ==================================

View File

@ -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>