diff --git a/cmake/src/build_options.cmake b/cmake/src/build_options.cmake index 557d74dc0d698b3b509a177bf9af0e20a8412892..8f177c6500fc9d5259acc22b0df33ebb77d19d4d 100755 --- a/cmake/src/build_options.cmake +++ b/cmake/src/build_options.cmake @@ -150,6 +150,23 @@ if(${BUILD_TUPLE} STREQUAL "aarch64" AND ${ENABLE_NUMA} STREQUAL "ON") endif() endif() +option(HAS_RISCV_V_EXTENSION "enable the riscv v extension for vector operation" OFF) +message(STATUS "HAS_RISCV_V_EXTENSION = ${HAS_RISCV_V_EXTENSION}") +option(HAS_RISCV_ZBC_EXTENSION "enable the riscv zbc extension for crc32c operation" OFF) +message(STATUS "HAS_RISCV_ZBC_EXTENSION = ${HAS_RISCV_ZBC_EXTENSION}") +if(${BUILD_TUPLE} STREQUAL "riscv64") + set(OS_OPTIONS "-mcmodel=medany -march=rv64gc") + if(${HAS_RISCV_ZBC_EXTENSION} STREQUAL "ON") + set(OS_OPTIONS "${OS_OPTIONS}""_zbc") + endif() +endif() + +if(${BUILD_TUPLE} STREQUAL "riscv64" AND (${ENABLE_NUMA} STREQUAL "ON" OR ${ENABLE_MOT} STREQUAL "ON")) + if(NOT $ENV{DEBUG_TYPE} STREQUAL "memcheck") + set(DB_COMMON_DEFINE ${DB_COMMON_DEFINE} -D__USE_NUMA) + endif() +endif() + if(${ENABLE_LITE_MODE} STREQUAL "ON") set(ENABLE_LLVM_COMPILE OFF) set(ENABLE_GSS OFF) @@ -207,6 +224,9 @@ if(${BUILD_TUPLE} STREQUAL "x86_64") elseif(${BUILD_TUPLE} STREQUAL "aarch64") set(USE_SSE42_CRC32C_WITH_RUNTIME_CHECK OFF) set(ARCH_LLVMIR "_aarch64" CACHE INTERNAL "") +elseif(${BUILD_TUPLE} STREQUAL "riscv64") + set(USE_SSE42_CRC32C_WITH_RUNTIME_CHECK OFF) + set(ARCH_LLVMIR "_riscv64" CACHE INTERNAL "") endif() #The two libraries are also connected in a dynamic library, for static link: change -lasan -ltsan to -l:libasan.a -l:libtsan.a diff --git a/config/config.guess b/config/config.guess index 15f22ac76f7b787f05270113e8ce21a448358606..71c5ca385b39c7e55965d850cd28d3437921d6ed 100644 --- a/config/config.guess +++ b/config/config.guess @@ -963,6 +963,9 @@ EOF loongarch*:Linux:*:*) echo "$UNAME_MACHINE"-linux-"$LIBC" exit ;; + riscv32:Linux:*:* | riscv64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c diff --git a/config/config.sub b/config/config.sub index 6e5c23c538783b81be6d923131bef7aedadaaffb..581f910c2a8d5d45e4eb2caa1fbc25958927acbd 100644 --- a/config/config.sub +++ b/config/config.sub @@ -275,6 +275,7 @@ case $basic_machine in | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | mcore | mep | metag \ | loongarch32 | loongarch64 \ + | riscv32 | riscv64 \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ @@ -392,6 +393,7 @@ case $basic_machine in | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ | loongarch32-* | loongarch64-* \ + | riscv32-* | riscv64-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ diff --git a/configure b/configure index 02d3c947a90e2384a86a2cba4a6b922bc77be0c3..7072b19135839bcdb6fd6d54aec80bc0f112a1fa 100755 --- a/configure +++ b/configure @@ -761,6 +761,8 @@ enable_mot enable_x86_rdtscp enable_htap enable_bbox +has_riscv_v_extension +has_riscv_zbc_extension enable_memory_check enable_mysql_fdw enable_oracle_fdw @@ -852,6 +854,8 @@ enable_mot enable_x86_rdtscp enable_htap enable_bbox +has_riscv_v_extension +has_riscv_zbc_extension enable_memory_check enable_mysql_fdw enable_oracle_fdw @@ -1062,10 +1066,27 @@ do "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; + ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; + -has-* | --has-*) + ac_useropt=`expr "x$ac_option" : 'x-*has-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 + { (exit 1); exit 1; }; } + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"has_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--has-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval has_$ac_useropt=\$ac_optarg ;; + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) @@ -3465,6 +3486,10 @@ if [[ "$(cat /etc/system-release)" =~ ^"openEuler release 22.03".* ]]; then with_openeuler_major=yes fi +if [[ "$(cat /etc/system-release)" =~ ^"openEuler release 23.09".* ]]; then + with_openeuler_major=yes +fi + if [[ "$(cat /etc/system-release)" =~ ^"openEuler release 24.03".* ]]; then with_openeuler_major=yes fi @@ -29147,6 +29172,48 @@ if [ "$PLATFORM_ARCH"X == "aarch64"X ] ; then else CFLAGS="-march=armv8-a+crc $CFLAGS" fi +elif [ "$PLATFORM_ARCH"X == "riscv64"X ] ; then + # Check whether --has-riscv-v-extension was given. + if test "${has_riscv_v_extension+set}" = set; then + enableval=$has_riscv_v_extension; + case $enableval in + yes) + : + ;; + no) + : + ;; + *) + has_riscv_v_extension=no + ;; + esac + else + has_riscv_v_extension=no + fi + + # Check whether --has-riscv-zbc-extension was given. + if test "${has_riscv_zbc_extension+set}" = set; then + enableval=$has_riscv_zbc_extension; + case $enableval in + yes) + : + ;; + no) + : + ;; + *) + has_riscv_zbc_extension=no + ;; + esac + else + has_riscv_zbc_extension=no + fi + + RISCV_FLAGS="-march=rv64gc" + if [ "$has_riscv_zbc_extension"X == "yes"X ]; then + RISCV_FLAGS=$RISCV_FLAGS"_zbc" + fi + CFLAGS="$RISCV_FLAGS $CFLAGS" elif [ "$PLATFORM_ARCH"X == "x86_64"X ] ; then CFLAGS="-mcx16 $CFLAGS_SSE42 $CFLAGS" else @@ -29225,6 +29292,11 @@ $as_echo "SSE 4.2 with runtime check" >&6; } PG_CRC32C_OBJS="pg_crc32c_choose.o" { $as_echo "$as_me:${as_lineno-$LINENO}: result: ARM CRC32C" >&5 $as_echo "ARM CRC32C" >&6; } + elif test x"$has_riscv_zbc_extension" = x"yes"; then + + PG_CRC32C_OBJS="pg_crc32c_riscv_zbc.o" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: RISCV CRC32C" >&5 +$as_echo "RISCV CRC32C" >&6; } else $as_echo "#define USE_SLICING_BY_8_CRC32C 1" >>confdefs.h diff --git a/src/Makefile.global.in b/src/Makefile.global.in index 550dcd2959a6d92f6c886dfb616cdfd59d43bddc..28408089f99d85f831e97d8a02e392befd0b25a6 100644 --- a/src/Makefile.global.in +++ b/src/Makefile.global.in @@ -179,6 +179,8 @@ enable_finance_mode = @enable_finance_mode@ enable_mot = @enable_mot@ enable_x86_rdtscp = @enable_x86_rdtscp@ enable_bbox = @enable_bbox@ +has_riscv_v_extension = @has_riscv_v_extension@ +has_riscv_zbc_extension = @has_riscv_zbc_extension@ enable_llvm = @enable_llvm@ enable_mysql_fdw = @enable_mysql_fdw@ enable_oracle_fdw = @enable_oracle_fdw@ diff --git a/src/bin/pg_probackup/atomics.h b/src/bin/pg_probackup/atomics.h index f28d7d0767194d33dfd26eb83d257d778099ee0e..f485d9998f5dae8a4c4a421747aad9da06a4f255 100644 --- a/src/bin/pg_probackup/atomics.h +++ b/src/bin/pg_probackup/atomics.h @@ -75,6 +75,8 @@ #include "atomics/arch-ppc.h" #elif defined(__hppa) || defined(__hppa__) #include "atomics/arch-hppa.h" +#elif defined(__riscv) +#include "atomics/arch-riscv.h" #endif /* diff --git a/src/bin/pg_probackup/atomics/arch-riscv.h b/src/bin/pg_probackup/atomics/arch-riscv.h new file mode 100644 index 0000000000000000000000000000000000000000..d8e1355c1a6e44ea685de7c9fbaca95bcb6ff338 --- /dev/null +++ b/src/bin/pg_probackup/atomics/arch-riscv.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2025 Institute of Software, CAS. + * Author : huangji@iscas.ac.cn + * + * openGauss is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * --------------------------------------------------------------------------------------- + * + * IDENTIFICATION + * src/bin/pg_probackup/atomics/arch-riscv.h + * + * --------------------------------------------------------------------------------------- + */ + +/* intentionally no include guards, should only be included by atomics.h */ +#ifndef INSIDE_ATOMICS_H +#error "should be included via atomics.h" +#endif + +#if !defined(__riscv) && !(__riscv_xlen == 64) +#define PG_DISABLE_64_BIT_ATOMICS +#endif /* __riscv */ \ No newline at end of file diff --git a/src/common/backend/utils/adt/CMakeLists.txt b/src/common/backend/utils/adt/CMakeLists.txt index 0403fb176a1abbd4e47a6673aa0ea9c5be38d1a3..a1371276b6de0e9af040a7d34bfb2449767372e8 100755 --- a/src/common/backend/utils/adt/CMakeLists.txt +++ b/src/common/backend/utils/adt/CMakeLists.txt @@ -52,6 +52,10 @@ set_source_files_properties( PROPERTIES COMPILE_OPTIONS "${datavec_OPTFLAGS}" ) +if (HAS_RISCV_V_EXTENSION) + set_source_files_properties(SOURCE vector.cpp APPEND PROPERTIES COMPILE_FLAGS "-march=rv64gcv") +endif (HAS_RISCV_V_EXTENSION) + set(adt_DEF_OPTIONS ${MACRO_OPTIONS}) set(adt_COMPILE_OPTIONS ${OPTIMIZE_OPTIONS} ${OS_OPTIONS} ${PROTECT_OPTIONS} ${WARNING_OPTIONS} ${BIN_SECURE_OPTIONS} ${CHECK_OPTIONS}) set(adt_LINK_OPTIONS ${BIN_LINK_OPTIONS}) diff --git a/src/common/backend/utils/adt/Makefile b/src/common/backend/utils/adt/Makefile index 9b71367ca7ca6f43c50cd5eb6173311d2bf95d32..b67f583bf568aab9389e9e33371e14ce9ff73f57 100644 --- a/src/common/backend/utils/adt/Makefile +++ b/src/common/backend/utils/adt/Makefile @@ -54,6 +54,14 @@ ifneq ($(filter ppc64%, $(shell uname -m)), ) VECTOR_OPT = endif +ifeq ($(shell uname -m), riscv64) + VECTOR_OPT = +endif + +ifeq (${has_riscv_v_extension}, yes) +vector.o: CFLAGS += -march=rv64gcv +endif + VECTOR_CFLAGS += $(VECTOR_OPT) -ftree-vectorize -fassociative-math -fno-signed-zeros -fno-trapping-math VECTOR_SRC = bitvec.o f2s.o halfutils.o halfvec.o sparsevec.o vector.o diff --git a/src/common/backend/utils/adt/vector.cpp b/src/common/backend/utils/adt/vector.cpp index 83cf27c0b3b5e4ade740deb40d74cb5219fc415e..f6bdc4518665982b542fc6fa16701210baff7903 100644 --- a/src/common/backend/utils/adt/vector.cpp +++ b/src/common/backend/utils/adt/vector.cpp @@ -26,6 +26,10 @@ #ifdef __aarch64__ #include +#elif defined(__riscv) +#ifdef __riscv_vector +#include +#endif #else #include #endif @@ -639,6 +643,7 @@ Datum halfvec_to_vector(PG_FUNCTION_ARGS) PG_RETURN_POINTER(result); } +#ifndef __riscv inline void prefetch_L1(const void *address) { #if defined(__SSE2__) @@ -649,6 +654,7 @@ inline void prefetch_L1(const void *address) __builtin_prefetch(address, 0, 3); // L3 cache #endif } +#endif #ifdef __aarch64__ static float L2SquaredDistanceRef(int dim, float *ax, float *bx) @@ -709,6 +715,28 @@ VectorL2SquaredDistance(int dim, float *ax, float *bx) } return distance; } + +#elif defined(__riscv_vector) +VECTOR_TARGET_CLONES float +VectorL2SquaredDistance(int dim, float *ax, float *bx) +{ + size_t vlmax = __riscv_vsetvlmax_e32m2(); + vfloat32m2_t vec_s = __riscv_vfmv_v_f_f32m2(0.0, vlmax); + vfloat32m1_t vec_zero = __riscv_vfmv_v_f_f32m1(0.0, vlmax); + + for (size_t vl; dim > 0; dim -= vl, ax += vl, bx += vl) { + vl = __riscv_vsetvl_e32m2(dim); + vfloat32m2_t vec_a = __riscv_vle32_v_f32m2(ax, vl); + vfloat32m2_t vec_b = __riscv_vle32_v_f32m2(bx, vl); + vfloat32m2_t vec_diff = __riscv_vfsub_vv_f32m2(vec_a, vec_b, vl); + vec_s = __riscv_vfmacc_vv_f32m2_tu(vec_s, vec_diff, vec_diff, vl); + } + + vfloat32m1_t vec_sum = __riscv_vfredusum_vs_f32m2_f32m1(vec_s, vec_zero, vlmax); + + return __riscv_vfmv_f_s_f32m1_f32(vec_sum); +} + #elif defined(__x86_64__) && defined(__AVX__) static inline __m128 masked_read(int d, const float *x) { @@ -848,6 +876,27 @@ VectorInnerProduct(int dim, float *ax, float *bx) } return dis; } + +#elif defined(__riscv_vector) +VECTOR_TARGET_CLONES float +VectorInnerProduct(int dim, float *ax, float *bx) +{ + size_t vlmax = __riscv_vsetvlmax_e32m2(); + vfloat32m2_t vec_s = __riscv_vfmv_v_f_f32m2(0.0, vlmax); + vfloat32m1_t vec_zero = __riscv_vfmv_v_f_f32m1(0.0, vlmax); + + for (size_t vl; dim > 0; dim -= vl, ax += vl, bx += vl) { + vl = __riscv_vsetvl_e32m2(dim); + vfloat32m2_t vec_a = __riscv_vle32_v_f32m2(ax, vl); + vfloat32m2_t vec_b = __riscv_vle32_v_f32m2(bx, vl); + vec_s = __riscv_vfmacc_vv_f32m2_tu(vec_s, vec_a, vec_b, vl); + } + + vfloat32m1_t vec_sum = __riscv_vfredusum_vs_f32m2_f32m1(vec_s, vec_zero, vlmax); + + return __riscv_vfmv_f_s_f32m1_f32(vec_sum); +} + #else VECTOR_TARGET_CLONES float VectorInnerProduct(int dim, float *ax, float *bx) @@ -1556,6 +1605,21 @@ void VectorMadd(size_t n, const float *ax, float bf, const float *bx, float *cx) cx[i] = ax[i] + bf * bx[i]; } } +#elif defined(__riscv_vector) +void VectorMadd(size_t n, const float *ax, float bf, const float *bx, float *cx) +{ + float *ptr_ax = (float *)ax; + float *ptr_bx = (float *)bx; + + for (size_t vl; n > 0; n -= vl, ptr_ax += vl, ptr_bx += vl, cx += vl) { + vl = __riscv_vsetvl_e32m2(n); + vfloat32m2_t vec_a = __riscv_vle32_v_f32m2(ptr_ax, vl); + vfloat32m2_t vec_b = __riscv_vle32_v_f32m2(ptr_bx, vl); + vfloat32m2_t vec_c = __riscv_vfmacc_vf_f32m2(vec_a, bf, vec_b, vl); + __riscv_vse32_v_f32m2(cx, vec_c, vl); + } +} + #else void VectorMadd(size_t n, const float *ax, float bf, const float *bx, float *cx) { diff --git a/src/common/backend/utils/error/fatal_err.cpp b/src/common/backend/utils/error/fatal_err.cpp index f491b1ce2613fa40cdcbcaa254cbd23c3c507835..b962c117e5bc8c2365eacfdc1775954bdb73a67b 100644 --- a/src/common/backend/utils/error/fatal_err.cpp +++ b/src/common/backend/utils/error/fatal_err.cpp @@ -137,6 +137,17 @@ static uintptr_t get_sp(const ucontext_t *uc) { return (uintptr_t)uc->uc_mcontext.sp; } +#elif __riscv +static uintptr_t get_pc(const ucontext_t *uc) +{ + return (uintptr_t)uc->uc_mcontext.__gregs[REG_PC]; +} + +static uintptr_t get_sp(const ucontext_t *uc) +{ + return (uintptr_t)uc->uc_mcontext.__gregs[REG_SP]; +} + #else #define get_pc(uc) 0 #define get_sp(uc) 0 diff --git a/src/common/port/CMakeLists.txt b/src/common/port/CMakeLists.txt index b9a6a282ae6c7b4e745f5243a1c26ad0828176c3..771bd3d38dec2e7bbbb5485a786a9b0802d4dfd2 100755 --- a/src/common/port/CMakeLists.txt +++ b/src/common/port/CMakeLists.txt @@ -9,6 +9,7 @@ execute_process( COMMAND ln -fs ${CMAKE_CURRENT_SOURCE_DIR}/strlcpy.cpp ${CMAKE_CURRENT_SOURCE_DIR}/port_srv/strlcpy.cpp COMMAND ln -fs ${CMAKE_CURRENT_SOURCE_DIR}/getpeereid.cpp ${CMAKE_CURRENT_SOURCE_DIR}/port_srv/getpeereid.cpp COMMAND ln -fs ${CMAKE_CURRENT_SOURCE_DIR}/pg_crc32c_sse42.cpp ${CMAKE_CURRENT_SOURCE_DIR}/port_srv/pg_crc32c_sse42.cpp + COMMAND ln -fs ${CMAKE_CURRENT_SOURCE_DIR}/pg_crc32c_riscv_zbc.cpp ${CMAKE_CURRENT_SOURCE_DIR}/port_srv/pg_crc32c_riscv_zbc.cpp COMMAND ln -fs ${CMAKE_CURRENT_SOURCE_DIR}/pg_crc32c_sb8.cpp ${CMAKE_CURRENT_SOURCE_DIR}/port_srv/pg_crc32c_sb8.cpp COMMAND ln -fs ${CMAKE_CURRENT_SOURCE_DIR}/pg_crc32c_choose.cpp ${CMAKE_CURRENT_SOURCE_DIR}/port_srv/pg_crc32c_choose.cpp COMMAND ln -fs ${CMAKE_CURRENT_SOURCE_DIR}/chklocale.cpp ${CMAKE_CURRENT_SOURCE_DIR}/port_srv/chklocale.cpp @@ -94,6 +95,15 @@ if("${BUILD_TUPLE}" STREQUAL "loongarch64") list(REMOVE_ITEM TGT_port_SRC ${CMAKE_CURRENT_SOURCE_DIR}/pg_crc32c_choose.cpp ${CMAKE_CURRENT_SOURCE_DIR}/pg_crc32c_sse42.cpp) endif() +# riscv64 +if("${BUILD_TUPLE}" STREQUAL "riscv64") + list(REMOVE_ITEM TGT_port_SRC ${CMAKE_CURRENT_SOURCE_DIR}/pg_crc32c_choose.cpp ${CMAKE_CURRENT_SOURCE_DIR}/pg_crc32c_sse42.cpp) + if (HAS_RISCV_ZBC_EXTENSION) + list(REMOVE_ITEM TGT_port_SRC ${CMAKE_CURRENT_SOURCE_DIR}/pg_crc32c_sb8.cpp) + list(APPEND TGT_port_SRC ${CMAKE_CURRENT_SOURCE_DIR}/pg_crc32c_riscv_zbc.cpp) + endif (HAS_RISCV_ZBC_EXTENSION) +endif() + SET(TGT_pgport_INC ${PROJECT_SRC_DIR}/common/backend ${PROJECT_SRC_DIR}/common/port @@ -167,6 +177,15 @@ if("${BUILD_TUPLE}" STREQUAL "loongarch64") list(REMOVE_ITEM TGT_pgport_srv_SRC ${CMAKE_CURRENT_SOURCE_DIR}/port_srv/pg_crc32c_choose.cpp ${CMAKE_CURRENT_SOURCE_DIR}/port_srv/pg_crc32c_sse42.cpp) endif() +# riscv64 +if("${BUILD_TUPLE}" STREQUAL "riscv64") + list(REMOVE_ITEM TGT_pgport_srv_SRC ${CMAKE_CURRENT_SOURCE_DIR}/port_srv/pg_crc32c_choose.cpp ${CMAKE_CURRENT_SOURCE_DIR}/port_srv/pg_crc32c_sse42.cpp) + if (HAS_RISCV_ZBC_EXTENSION) + list(REMOVE_ITEM TGT_pgport_srv_SRC ${CMAKE_CURRENT_SOURCE_DIR}/port_srv/pg_crc32c_sb8.cpp) + list(APPEND TGT_pgport_srv_SRC ${CMAKE_CURRENT_SOURCE_DIR}/port_srv/pg_crc32c_riscv_zbc.cpp) + endif (HAS_RISCV_ZBC_EXTENSION) +endif() + SET(TGT_pgport_srv_INC ${PROJECT_SRC_DIR}/common/backend ${PROJECT_SRC_DIR}/common/port diff --git a/src/common/port/Makefile b/src/common/port/Makefile index c3d78c261e1a140ec24a1940cf1b811f43b33c0c..5142fbd967e3cfd8c55c5dc349b739b5330705ae 100644 --- a/src/common/port/Makefile +++ b/src/common/port/Makefile @@ -57,6 +57,8 @@ ifeq "${host_cpu}" "aarch64" OBJS += pg_crc32c_choose.o else ifeq "${host_cpu}" "x86_64" OBJS += pg_crc32c_sse42.o pg_crc32c_sb8.o pg_crc32c_choose.o +else ifeq "${has_riscv_zbc_extension}" "yes" +OBJS += pg_crc32c_riscv_zbc.o else OBJS += pg_crc32c_sb8.o endif @@ -113,6 +115,9 @@ CFLAGS_SSE42=-msse4.2 pg_crc32c_sse42.o: CFLAGS+=$(CFLAGS_SSE42) pg_crc32c_sse42_srv.o: CFLAGS+=$(CFLAGS_SSE42) +CFLAGS_ZBC="-march=rv64gc_zbc" +pg_crc32c_riscv_zbc.o: CFLAGS+=$(CFLAGS_ZBC) +pg_crc32c_riscv_zbc_srv.o: CFLAGS+=$(CFLAGS_ZBC) # # Server versions of object files # diff --git a/src/common/port/pg_crc32c_riscv_zbc.cpp b/src/common/port/pg_crc32c_riscv_zbc.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0ef8d9ab205b395e44c85756d0540d8713219e92 --- /dev/null +++ b/src/common/port/pg_crc32c_riscv_zbc.cpp @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2025 Institute of Software, CAS. + * Author : huangji@iscas.ac.cn + * + * openGauss is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * --------------------------------------------------------------------------------------- + * + * IDENTIFICATION + * src/common/port/pg_crc32c_riscv_zbc.cpp + * + * --------------------------------------------------------------------------------------- + */ + +#include "c.h" + +#include "port/pg_crc32c.h" + +#if defined(__riscv_zbc) +#if __riscv_xlen == 64 +/* Slide by XLEN bits per iteration */ +# define STEP_ORDER 3 + +/* Each below polynomial quotient has an implicit bit for 2^XLEN */ + +/* Polynomial quotient of (2^(XLEN+32))/CRC32C_POLY, in LE format */ +# define CRC32C_POLY_QT_LE 0xa434f61c6f5389f8 + +static inline uint64 crc32_le_prep(uint32 crc, unsigned long const *ptr) +{ + return (uint64)crc ^ (uint64)(*ptr); +} + +static inline uint32 crc32_le_zbc(unsigned long s, uint32 poly, unsigned long poly_qt) +{ + uint32 crc; + + /* We don't have a "clmulrh" insn, so use clmul + slli instead. */ + __asm__ volatile (".option push\n" + ".option arch,+zbc\n" + "clmul %0, %1, %2\n" + "slli %0, %0, 1\n" + "xor %0, %0, %1\n" + "clmulr %0, %0, %3\n" + "srli %0, %0, 32\n" + ".option pop\n" + : "=&r" (crc) + : "r" (s), + "r" (poly_qt), + "r" ((uint64)poly << 32) + :); + return crc; +} + +#elif __riscv_xlen == 32 +# define STEP_ORDER 2 +/* Each quotient should match the upper half of its analog in RV64 */ +# define CRC32C_POLY_QT_LE 0x6f5389f8 + +static inline uint32 crc32_le_prep(uint32 crc, unsigned long const *ptr) +{ + return crc ^ (uint32)(*ptr); +} + +static inline uint32 crc32_le_zbc(unsigned long s, uint32 poly, unsigned long poly_qt) +{ + uint32 crc; + + /* We don't have a "clmulrh" insn, so use clmul + slli instead. */ + __asm__ volatile (".option push\n" + ".option arch,+zbc\n" + "clmul %0, %1, %2\n" + "slli %0, %0, 1\n" + "xor %0, %0, %1\n" + "clmulr %0, %0, %3\n" + ".option pop\n" + : "=&r" (crc) + : "r" (s), + "r" (poly_qt), + "r" (poly) + :); + return crc; +} +#endif + +#define STEP (1 << STEP_ORDER) +#define OFFSET_MASK (STEP - 1) +#define CRC32C_POLY_LE 0x82F63B78 +#define min(X,Y) ((X) < (Y) ? (X) : (Y)) + +static inline uint32 crc32_le_unaligned(uint32 crc, unsigned char const *p, + size_t len, uint32 poly, + unsigned long poly_qt) +{ + size_t bits = len * 8; + unsigned long s = 0; + uint32 crc_low = 0; + + for (size_t i = 0; i < len; i++) + s = ((unsigned long)*p++ << (__riscv_xlen - 8)) | (s >> 8); + + s ^= (unsigned long)crc << (__riscv_xlen - bits); + if (__riscv_xlen == 32 || len < sizeof(uint32)) + crc_low = crc >> bits; + + crc = crc32_le_zbc(s, poly, poly_qt); + crc ^= crc_low; + + return crc; +} + +static inline uint32 crc32_le_generic(uint32 crc, unsigned char const *p, + size_t len, uint32 poly, + unsigned long poly_qt) +{ + size_t offset, head_len, tail_len; + unsigned long const *p_ul; + unsigned long s; + + /* Handle the unaligned head. */ + offset = (unsigned long)p & OFFSET_MASK; + if (offset && len) { + head_len = min(STEP - offset, len); + crc = crc32_le_unaligned(crc, p, head_len, poly, poly_qt); + p += head_len; + len -= head_len; + } + + tail_len = len & OFFSET_MASK; + len = len >> STEP_ORDER; + p_ul = (unsigned long const *)p; + + for (size_t i = 0; i < len; i++) { + s = crc32_le_prep(crc, p_ul); + crc = crc32_le_zbc(s, poly, poly_qt); + p_ul++; + } + + /* Handle the tail bytes. */ + p = (unsigned char const *)p_ul; + if (tail_len) + crc = crc32_le_unaligned(crc, p, tail_len, poly, poly_qt); + + return crc; +} + +pg_crc32c pg_comp_crc32c_zbc(pg_crc32c crc, const void* data, size_t len) +{ + return crc32_le_generic(crc, static_cast(data), len, CRC32C_POLY_LE, + CRC32C_POLY_QT_LE); +} + +#endif \ No newline at end of file diff --git a/src/gausskernel/dbmind/db4ai/executor/CMakeLists.txt b/src/gausskernel/dbmind/db4ai/executor/CMakeLists.txt index 6803a3d36888024eb9d6ee4fe83536752e922520..8fa18ee63b1cee7bdc8d843d2d9edb3a00ef9ac9 100755 --- a/src/gausskernel/dbmind/db4ai/executor/CMakeLists.txt +++ b/src/gausskernel/dbmind/db4ai/executor/CMakeLists.txt @@ -26,5 +26,10 @@ endif() set(executor_LINK_OPTIONS ${BIN_LINK_OPTIONS}) add_static_objtarget(gausskernel_db4ai_executor TGT_executor_SRC TGT_executor_INC "${executor_DEF_OPTIONS}" "${executor_COMPILE_OPTIONS}" "${executor_LINK_OPTIONS}") +if (HAS_RISCV_V_EXTENSION) + set_source_files_properties(SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/distance_functions.cpp + APPEND PROPERTIES COMPILE_FLAGS "-march=rv64gcv") +endif (HAS_RISCV_V_EXTENSION) + add_subdirectory(optimize) add_subdirectory(algorithms) diff --git a/src/gausskernel/dbmind/db4ai/executor/Makefile b/src/gausskernel/dbmind/db4ai/executor/Makefile index 9fa2ae836e756fc08f469b2b654ac672fdd9dd64..f9ea2ee2d05af5b99b4946725bde8c79ccaf6b7a 100644 --- a/src/gausskernel/dbmind/db4ai/executor/Makefile +++ b/src/gausskernel/dbmind/db4ai/executor/Makefile @@ -27,4 +27,8 @@ endif SUBDIRS = algorithms optimize OBJS = fp_ops.o distance_functions.o hyperparameter_validation.o direct.o kernel.o matrix.o +ifeq (${has_riscv_v_extension}, yes) +distance_functions.o: CPPFLAGS+= -march=rv64gcv +endif + include $(top_srcdir)/src/gausskernel/common.mk diff --git a/src/gausskernel/dbmind/db4ai/executor/distance_functions.cpp b/src/gausskernel/dbmind/db4ai/executor/distance_functions.cpp index af759c590632e0f0b0a794f8e5ce2d9fc74672b9..8ec70f51907ae41e8a7a2fe06b684dbb1caf9eb4 100644 --- a/src/gausskernel/dbmind/db4ai/executor/distance_functions.cpp +++ b/src/gausskernel/dbmind/db4ai/executor/distance_functions.cpp @@ -34,6 +34,10 @@ IDENTIFICATION #include #elif defined(__aarch64__) && defined(__ARM_NEON) #include +#elif defined(__riscv) +#ifdef __riscv_vector +#include +#endif #endif @@ -169,6 +173,30 @@ static double l1_128(double const * p, double const * q, uint32_t const dimensio return distance[0] + global_distance_correction; } +#elif (defined(__riscv) && defined(__riscv_vector)) +static double l1_128(double const * p, double const * q, uint32_t const dimension) +{ + size_t vlmax = __riscv_vsetvlmax_e64m2(); + vfloat64m2_t vec_s = __riscv_vfmv_v_f_f64m2(0.0, vlmax); + vfloat64m1_t vec_zero = __riscv_vfmv_v_f_f64m1(0.0, vlmax); + uint32_t dim = dimension; + double *ax = (double *)p; + double *bx = (double *)q; + + for (size_t vl; dim > 0; dim -= vl, ax += vl, bx += vl) { + vl = __riscv_vsetvl_e64m2(dim); + vfloat64m2_t vec_a = __riscv_vle64_v_f64m2(ax, vl); + vfloat64m2_t vec_b = __riscv_vle64_v_f64m2(bx, vl); + vfloat64m2_t vec_diff = __riscv_vfsub_vv_f64m2(vec_a, vec_b, vl); + vfloat64m2_t vec_abs_diff = __riscv_vfabs_v_f64m2(vec_diff, vl); + vec_s = __riscv_vfadd_vv_f64m2(vec_s, vec_abs_diff, vl); + } + + vfloat64m1_t vec_sum = __riscv_vfredusum_vs_f64m2_f64m1(vec_s, vec_zero, vlmax); + + return __riscv_vfmv_f_s_f64m1_f64(vec_sum); +} + #endif @@ -305,6 +333,29 @@ static double l2_squared_128(double const * p, double const * q, uint32_t const return distance[0] + global_distance_correction; } +#elif (defined(__riscv) && defined(__riscv_vector)) +static double l2_squared_128(double const * p, double const * q, uint32_t const dimension) +{ + size_t vlmax = __riscv_vsetvlmax_e64m2(); + vfloat64m2_t vec_s = __riscv_vfmv_v_f_f64m2(0.0, vlmax); + vfloat64m1_t vec_zero = __riscv_vfmv_v_f_f64m1(0.0, vlmax); + uint32_t dim = dimension; + double *ax = (double *)p; + double *bx = (double *)q; + + for (size_t vl; dim > 0; dim -= vl, ax += vl, bx += vl) { + vl = __riscv_vsetvl_e64m2(dim); + vfloat64m2_t vec_a = __riscv_vle64_v_f64m2(ax, vl); + vfloat64m2_t vec_b = __riscv_vle64_v_f64m2(bx, vl); + vfloat64m2_t vec_diff = __riscv_vfsub_vv_f64m2(vec_a, vec_b, vl); + vec_s = __riscv_vfmacc_vv_f64m2_tu(vec_s, vec_diff, vec_diff, vl); + } + + vfloat64m1_t vec_sum = __riscv_vfredusum_vs_f64m2_f64m1(vec_s, vec_zero, vlmax); + + return __riscv_vfmv_f_s_f64m1_f64(vec_sum); +} + #endif /* @@ -418,6 +469,30 @@ static double linf_128(double const * p, double const * q, uint32_t const dimens return result; } +#elif (defined(__riscv) && defined(__riscv_vector)) +static double linf_128(double const * p, double const * q, uint32_t const dimension) +{ + size_t vlmax = __riscv_vsetvlmax_e64m2(); + vfloat64m2_t vec_m = __riscv_vfmv_v_f_f64m2(0.0, vlmax); + vfloat64m1_t vec_zero = __riscv_vfmv_v_f_f64m1(0.0, vlmax); + uint32_t dim = dimension; + double *ax = (double *)p; + double *bx = (double *)q; + + for (size_t vl; dim > 0; dim -= vl, ax += vl, bx += vl) { + vl = __riscv_vsetvl_e64m2(dim); + vfloat64m2_t vec_a = __riscv_vle64_v_f64m2(ax, vl); + vfloat64m2_t vec_b = __riscv_vle64_v_f64m2(bx, vl); + vfloat64m2_t vec_diff = __riscv_vfsub_vv_f64m2(vec_a, vec_b, vl); + vfloat64m2_t vec_abs_diff = __riscv_vfabs_v_f64m2(vec_diff, vl); + vec_m = __riscv_vfmax_vv_f64m2(vec_m, vec_abs_diff, vl); + } + + vfloat64m1_t vec_max = __riscv_vfredmax_vs_f64m2_f64m1(vec_m, vec_zero, vlmax); + + return __riscv_vfmv_f_s_f64m1_f64(vec_max); +} + #endif /* @@ -434,7 +509,8 @@ double l1(double const * p, double const * q, uint32_t const dimension) * depending on the feature of the underlying processor we vectorized one way * or another. in the worst case we do not vectorized at all */ -#if (defined(__x86_64__) && defined(__SSE3__)) || (defined(__aarch64__) && defined(__ARM_NEON)) +#if (defined(__x86_64__) && defined(__SSE3__)) || (defined(__aarch64__) && defined(__ARM_NEON)) \ + || (defined(__riscv) && defined(__riscv_vector)) return l1_128(p, q, dimension); #else return l1_non_vectorized(p, q, dimension); @@ -455,7 +531,8 @@ double l2_squared(double const * p, double const * q, uint32_t const dimension) * depending on the feature of the underlying processor we vectorized one way * or another. in the worst case we do not vectorized at all */ -#if (defined(__x86_64__) && defined(__SSE3__)) || (defined(__aarch64__) && defined(__ARM_NEON)) +#if (defined(__x86_64__) && defined(__SSE3__)) || (defined(__aarch64__) && defined(__ARM_NEON)) \ + || (defined(__riscv) && defined(__riscv_vector)) return l2_squared_128(p, q, dimension); #else return l2_squared_non_vectorized(p, q, dimension); @@ -497,7 +574,8 @@ double linf(double const * p, double const * q, uint32_t const dimension) * depending on the feature of the underlying processor we vectorized one way * or another. in the worst case we do not vectorized at all */ -#if (defined(__x86_64__) && defined(__SSE3__)) || (defined(__aarch64__) && defined(__ARM_NEON)) +#if (defined(__x86_64__) && defined(__SSE3__)) || (defined(__aarch64__) && defined(__ARM_NEON)) \ + || (defined(__riscv) && defined(__riscv_vector)) return linf_128(p, q, dimension); #else return linf_non_vectorized(p, q, dimension); diff --git a/src/gausskernel/runtime/executor/instrument.cpp b/src/gausskernel/runtime/executor/instrument.cpp index b4005ce3473f1199478e7577636f06cfb912a048..4293198749d4f4f92f126869167c12eded713112 100644 --- a/src/gausskernel/runtime/executor/instrument.cpp +++ b/src/gausskernel/runtime/executor/instrument.cpp @@ -93,6 +93,23 @@ static inline uint64 rdtsc(void) asm volatile("rdtsc" : "=a"(lo), "=d"(hi)); return ((uint64)lo) | (((uint64)hi) << 32); +#elif defined(__riscv) +#if __riscv_xlen == 64 + uint64_t cval = 0; + asm volatile("rdtime %0" : "=r"(cval)); + return cval; +#elif __riscv_xlen == 32 + uint32_t low, high, tmp; + asm volatile( + "1:\n" + "rdtimeh %0\n" + "rdtime %1\n" + "rdtimeh %2\n" + "bne %0, %2, 1b" + : "=&r" (high), "=&r" (low), "=&r" (tmp)); + return ((uint64_t)high << 32) | low; +#endif + #else return clock(); #endif diff --git a/src/gausskernel/runtime/vecexecutor/vectorsonic/vsonichash.cpp b/src/gausskernel/runtime/vecexecutor/vectorsonic/vsonichash.cpp index 4f1b28959dbe477ec8340f1a8fe92a074f6d1540..6a654902b69c824a89116061b0d8136b40a094e2 100644 --- a/src/gausskernel/runtime/vecexecutor/vectorsonic/vsonichash.cpp +++ b/src/gausskernel/runtime/vecexecutor/vectorsonic/vsonichash.cpp @@ -46,6 +46,15 @@ extern bool anls_opt_is_on(AnalysisOpt dfx_opt); #define HASH_INT32_CRC(c, k) __crc32cw(c, k) #elif defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__)) #define HASH_INT32_CRC(c, k) _mm_crc32_u32(c, k) +#elif defined(__riscv_zbc) +FORCE_INLINE + +uint32 __crc32cw_normal(uint32 seed, int32 key) +{ + return pg_comp_crc32c_zbc(seed, (const unsigned char *)&key, 4); +} + +#define HASH_INT32_CRC(c, k) __crc32cw_normal(c, k) #else FORCE_INLINE @@ -105,6 +114,8 @@ uint32 hashquickany(uint32 seed, register const unsigned char* data, register in crc = _mm_crc32_u8(crc, *p); p++; } +#elif defined(__riscv_zbc) + crc = pg_comp_crc32c_zbc(seed, data, len); #else crc = pg_comp_crc32c_sb8(seed, data, len); #endif diff --git a/src/gausskernel/storage/access/redo/standby_read/CMakeLists.txt b/src/gausskernel/storage/access/redo/standby_read/CMakeLists.txt index 7f8959afaf1610c56a36744a4550818089951a54..1e33a7e6a7cfc27ad5a282a57b1fd5ffc794a5f1 100644 --- a/src/gausskernel/storage/access/redo/standby_read/CMakeLists.txt +++ b/src/gausskernel/storage/access/redo/standby_read/CMakeLists.txt @@ -16,7 +16,7 @@ set(TGT_standby_read_INC ${LZ4_INCLUDE_PATH} ${EVENT_INCLUDE_PATH} ) - + set(standby_read_DEF_OPTIONS ${MACRO_OPTIONS}) set(standby_read_COMPILE_OPTIONS ${OPTIMIZE_OPTIONS} ${OS_OPTIONS} ${PROTECT_OPTIONS} ${WARNING_OPTIONS} ${BIN_SECURE_OPTIONS} ${CHECK_OPTIONS}) set(standby_read_LINK_OPTIONS ${BIN_LINK_OPTIONS}) diff --git a/src/gausskernel/storage/mot/core/CMakeLists.txt b/src/gausskernel/storage/mot/core/CMakeLists.txt index 4a40e701d254cc4b78fbf05547a8220e96d53460..8469da217ec27afc8ba66879019b3a426b982ec0 100644 --- a/src/gausskernel/storage/mot/core/CMakeLists.txt +++ b/src/gausskernel/storage/mot/core/CMakeLists.txt @@ -13,6 +13,8 @@ set(mot_core_COMPILE_OPTIONS ${OPTIMIZE_OPTIONS} ${OS_OPTIONS} ${PROTECT_OPTIONS -Wsizeof-pointer-memaccess -Winit-self -Wduplicated-cond -Wnon-virtual-dtor -std=gnu++11 -w -D_GLIBCXX_USE_CXX11_ABI=0 -fPIC -pthread -Wall) if(${BUILD_TUPLE} STREQUAL "aarch64") list(APPEND mot_core_COMPILE_OPTIONS -march=armv8-a+crc) +elseif(${BUILD_TUPLE} STREQUAL "riscv64") + list(APPEND mot_core_COMPILE_OPTIONS -march=rv64gc) else() list(APPEND mot_core_COMPILE_OPTIONS -mcx16) endif() diff --git a/src/gausskernel/storage/mot/core/Makefile.local b/src/gausskernel/storage/mot/core/Makefile.local index 8bb0709cf6eb5773f1092dfa870f872bea9fb836..6f769a3360d9397ca990408235ece086d9d44f36 100644 --- a/src/gausskernel/storage/mot/core/Makefile.local +++ b/src/gausskernel/storage/mot/core/Makefile.local @@ -72,6 +72,8 @@ PLATFORM_ARCH = $(shell uname -p) ifeq ($(PLATFORM_ARCH),aarch64) #CFLAGS += -std=gnu++11 -march=armv8-a+crc -Wall -Wextra -D_GLIBCXX_USE_CXX11_ABI=0 -fPIC CFLAGS += -std=gnu++11 -march=armv8-a+crc -w -D_GLIBCXX_USE_CXX11_ABI=0 -fPIC +else ifeq ($(PLATFORM_ARCH),riscv64) + CFLAGS += -std=gnu++11 -march=rv64gc -w -D_GLIBCXX_USE_CXX11_ABI=0 -fPIC else #CFLAGS += -std=gnu++11 -march=native -mcx16 -Wall -Wextra -D_GLIBCXX_USE_CXX11_ABI=0 -fPIC CFLAGS += -std=gnu++11 -mcx16 -w -D_GLIBCXX_USE_CXX11_ABI=0 -fPIC @@ -92,6 +94,8 @@ ifeq ($(UNDER_ENVELOPE), no) ifeq ($(BUILD),Release) ifeq ($(PLATFORM_ARCH),aarch64) CFLAGS += -O2 -DNDEBUG -D_FORTIFY_SOURCE=2 + else ifeq ($(PLATFORM_ARCH),riscv64) + CFLAGS += -O2 -DNDEBUG -D_FORTIFY_SOURCE=2 else CFLAGS += -Werror -O2 -DNDEBUG -mcx16 -D_FORTIFY_SOURCE=2 endif diff --git a/src/gausskernel/storage/mot/core/infra/synchronization/cycles.h b/src/gausskernel/storage/mot/core/infra/synchronization/cycles.h index 146f4b48d15a7ca4edb3d499a80b2d3875a8209c..233d747346a1330946eff6ff8f580e72ceb2473c 100644 --- a/src/gausskernel/storage/mot/core/infra/synchronization/cycles.h +++ b/src/gausskernel/storage/mot/core/infra/synchronization/cycles.h @@ -55,6 +55,23 @@ public: unsigned long cval = 0; asm volatile("isb; mrs %0, cntvct_el0" : "=r"(cval) : : "memory"); return cval; +#elif defined(__riscv) +#if __riscv_xlen == 64 + uint64_t cval = 0; + asm volatile("rdtime %0" : "=r"(cval)); + return cval; +#elif __riscv_xlen == 32 + uint32_t low, high, tmp; + asm volatile( + "1:\n" + "rdtimeh %0\n" + "rdtime %1\n" + "rdtimeh %2\n" + "bne %0, %2, 1b" + : "=&r" (high), "=&r" (low), "=&r" (tmp)); + return ((uint64_t)high << 32) | low; +#endif + #else #error "Unsupported CPU architecture or compiler." #endif @@ -87,6 +104,10 @@ public: unsigned long cval = 0; asm volatile("isb; mrs %0, cntvct_el0" : "=r"(cval) : : "memory"); return cval; +#elif defined(__riscv) + unsigned long cval = 0; + asm volatile("rdtime %0" : "=r"(cval) : : "memory"); + return cval; #else #error "Unsupported CPU architecture or compiler." #endif diff --git a/src/gausskernel/storage/mot/core/infra/synchronization/mot_atomic_ops.h b/src/gausskernel/storage/mot/core/infra/synchronization/mot_atomic_ops.h index 5b725e86c4fd3d2cf02f719ed59bff579a79487d..f6410e831a102e66f7fad4ca6c53f682a54d4579 100644 --- a/src/gausskernel/storage/mot/core/infra/synchronization/mot_atomic_ops.h +++ b/src/gausskernel/storage/mot/core/infra/synchronization/mot_atomic_ops.h @@ -31,6 +31,13 @@ #define MEMORY_BARRIER() asm volatile("lock; addl $0,0(%%rsp)" : : : "memory") #define READ_BARRIER() COMPILER_BARRIER #define WRITE_BARRIER() COMPILER_BARRIER +#elif defined(__riscv) /* riscv */ +#define COMPILER_BARRIER __sync_synchronize() +#define RISCV_FENCE(p, s) \ + __asm__ __volatile__ ("fence " #p "," #s : : : "memory") +#define MEMORY_BARRIER() RISCV_FENCE(rw,rw) +#define READ_BARRIER() RISCV_FENCE(r,r) +#define WRITE_BARRIER() RISCV_FENCE(w,w) /* end elif riscv */ #else #define COMPILER_BARRIER __sync_synchronize() #define MEMORY_BARRIER_DSB(opt) __asm__ __volatile__("DMB " #opt::: "memory") diff --git a/src/include/access/double_write_basic.h b/src/include/access/double_write_basic.h index a0502ad63216e40bf4de7340556ee7bb5833cc70..6f7a7d35070511c5f153500dcd9fdee815479119 100644 --- a/src/include/access/double_write_basic.h +++ b/src/include/access/double_write_basic.h @@ -145,7 +145,7 @@ const static uint32 DW_VIEW_COL_NAME_LEN = 32; typedef unsigned char slock_t; #endif -#if defined(__aarch64__) || defined(__aarch64) +#if defined(__aarch64__) || defined(__aarch64) || defined(__riscv) typedef int slock_t; #endif diff --git a/src/include/communication/commproxy_interface.h b/src/include/communication/commproxy_interface.h index 9b999cca1b6cdce146fd56cc16606aafe31c9786..671274aa20e2d3a225814a65fc974d0f257afa8a 100644 --- a/src/include/communication/commproxy_interface.h +++ b/src/include/communication/commproxy_interface.h @@ -420,6 +420,16 @@ extern bool comm_compare_and_swap_32(volatile int32* dest, int32 oldval, int32 n #define gaussdb_numa_memory_bind(i) #define gaussdb_numa_memory_unbind() +#elif defined(__riscv) /* riscv */ +#define RISCV_FENCE(p, s) \ + __asm__ __volatile__ ("fence " #p "," #s : : : "memory") +#define gaussdb_memory_barrier() RISCV_FENCE(rw,rw) +#define gaussdb_read_barrier() RISCV_FENCE(r,r) +#define gaussdb_write_barrier() RISCV_FENCE(w,w) /* end elif riscv */ + +#define gaussdb_numa_memory_bind(i) +#define gaussdb_numa_memory_unbind() + #else #define gaussdb_memory_barrier() __asm__ __volatile__("" ::: "memory") #define gaussdb_read_barrier() gaussdb_memory_barrier() diff --git a/src/include/gtm/gtm_slock.h b/src/include/gtm/gtm_slock.h index 1ba3e64f6e5e90e0f123474dece90065c32638a9..32b5a35212a93a3536b640d59ec0ecf997f43cb0 100644 --- a/src/include/gtm/gtm_slock.h +++ b/src/include/gtm/gtm_slock.h @@ -363,6 +363,45 @@ static __inline__ int tas(volatile slock_t* lock) #endif /* HAVE_GCC_INT_ATOMICS */ #endif /* __arm__ */ +/* riscv */ +#if defined(__riscv) +#define HAS_TEST_AND_SET + +#define TAS(lock) tas(lock) + +#ifdef HAVE_GCC_INT_ATOMICS + +typedef int slock_t; + +static __inline__ int tas(volatile slock_t* lock) +{ + return __sync_lock_test_and_set(lock, 1); +} + +#define S_UNLOCK(lock) __sync_lock_release(lock) + +#else /* !HAVE_GCC_INT_ATOMICS */ + +typedef unsigned int slock_t; + +static __inline__ int tas(volatile slock_t* lock) +{ + register slock_t _res = 1; + + __asm__ volatile( + "again: amoswap.w.aq %0, %0, (%1)\n" + " bnez %0, again\n" + " amoswap.w.rl x0, x0, (%1)\n" + : "+r"(_res), "+r"(lock) + : + : "memory" + ); + return (int)_res; +} + +#endif /* HAVE_GCC_INT_ATOMICS */ +#endif /* __riscv */ + /* S/390 and S/390x Linux (32- and 64-bit zSeries) */ #if defined(__s390__) || defined(__s390x__) #define HAS_TEST_AND_SET diff --git a/src/include/gtm/utils/barrier.h b/src/include/gtm/utils/barrier.h index 0c152d3a679ea853fc663dc907debd44f1600294..23eb09c1568f07ec45e4bef42135d8f100bda38c 100644 --- a/src/include/gtm/utils/barrier.h +++ b/src/include/gtm/utils/barrier.h @@ -118,6 +118,14 @@ } while (0) #endif + +#elif defined(__riscv) /* riscv */ +#define RISCV_FENCE(p, s) \ + __asm__ __volatile__ ("fence " #p "," #s : : : "memory") +#define pg_memory_barrier() RISCV_FENCE(rw,rw) +#define pg_read_barrier() RISCV_FENCE(r,r) +#define pg_write_barrier() RISCV_FENCE(w,w) /* end elif riscv */ + #elif defined(__ia64__) || defined(__ia64) /* diff --git a/src/include/port/pg_crc32c.h b/src/include/port/pg_crc32c.h index 1801e35ea790ccafd3f79f3a6a2e7ca910f3d906..5dce410526150c08093963100a5e292fd20fa8c5 100644 --- a/src/include/port/pg_crc32c.h +++ b/src/include/port/pg_crc32c.h @@ -81,6 +81,12 @@ extern pg_crc32c pg_comp_crc32c_sse42(pg_crc32c crc, const void* data, size_t le extern pg_crc32c pg_comp_crc32c_sb8(pg_crc32c crc, const void* data, size_t len); extern pg_crc32c (*pg_comp_crc32c)(pg_crc32c crc, const void* data, size_t len); +#elif defined(__riscv_zbc) +extern pg_crc32c pg_comp_crc32c_zbc(pg_crc32c crc, const void* data, size_t len); + +#define COMP_CRC32C(crc, data, len) ((crc) = pg_comp_crc32c_zbc((crc), (data), (len))) +#define FIN_CRC32C(crc) ((crc) ^= 0xFFFFFFFF) + #else /* * Use slicing-by-8 algorithm. diff --git a/src/include/storage/barrier.h b/src/include/storage/barrier.h index 82097cd5dcd9a92ae40f90c8656a26b80554f975..1861aad65c3d7981d7b8749ee2d1df426f83b9c5 100644 --- a/src/include/storage/barrier.h +++ b/src/include/storage/barrier.h @@ -117,6 +117,14 @@ } while (0) #endif + +#elif defined(__riscv) /* riscv */ +#define RISCV_FENCE(p, s) \ + __asm__ __volatile__ ("fence " #p "," #s : : : "memory") +#define pg_memory_barrier() RISCV_FENCE(rw,rw) +#define pg_read_barrier() RISCV_FENCE(r,r) +#define pg_write_barrier() RISCV_FENCE(w,w) /* end elif riscv */ + #elif defined(__ia64__) || defined(__ia64) /* diff --git a/src/include/storage/lock/s_lock.h b/src/include/storage/lock/s_lock.h index 715d84a64957536cebcbb5eee52da2796c974357..2a7db285ddd3062638c8056f9f908643e2e0ead1 100644 --- a/src/include/storage/lock/s_lock.h +++ b/src/include/storage/lock/s_lock.h @@ -380,6 +380,45 @@ static __inline__ int tas(volatile slock_t* lock) #endif /* HAVE_GCC_INT_ATOMICS */ #endif /* __arm__ */ +/* riscv */ +#if defined(__riscv) +#define HAS_TEST_AND_SET + +#define TAS(lock) tas(lock) + +#ifdef HAVE_GCC_INT_ATOMICS + +typedef int slock_t; + +static __inline__ int tas(volatile slock_t* lock) +{ + return __sync_lock_test_and_set(lock, 1); +} + +#define S_UNLOCK(lock) __sync_lock_release(lock) + +#else /* !HAVE_GCC_INT_ATOMICS */ + +typedef unsigned int slock_t; + +static __inline__ int tas(volatile slock_t* lock) +{ + register slock_t _res = 1; + + __asm__ volatile( + "again: amoswap.w.aq %0, %0, (%1)\n" + " bnez %0, again\n" + " amoswap.w.rl x0, x0, (%1)\n" + : "+r"(_res), "+r"(lock) + : + : "memory" + ); + return (int)_res; +} + +#endif /* HAVE_GCC_INT_ATOMICS */ +#endif /* __riscv */ + /* S/390 and S/390x Linux (32- and 64-bit zSeries) */ #if defined(__s390__) || defined(__s390x__) #define HAS_TEST_AND_SET