riscv64: Add initial support: test modifications

The following people contributed to the initial RISC-V support:
Petr Pavlu <petr.pavlu@dagobah.cz>
Xeonacid <h.dwwwwww@gmail.com>
laokz <laokz@foxmail.com>
Chelsea E. Manning <me@xychelsea.is>
zhaomingxin <zhaomingxin.zmx@alibaba-inc.com>
Jojo R <rjiejie@linux.alibaba.com>

Some integration fixes were added by Mark Wielaard <mark@klomp.org>
- helgrind/tests/tc11_XCHG.c: Fix XCHG_M_R guard

https://bugs.kde.org/show_bug.cgi?id=493507
This commit is contained in:
Petr Pavlu
2023-04-11 19:30:43 +00:00
committed by Mark Wielaard
parent 33833e37bf
commit e3432fc94d
15 changed files with 195 additions and 19 deletions

View File

@@ -314,6 +314,36 @@ UWord do_acasW ( UWord* addr, UWord expected, UWord nyu )
return success;
}
#elif defined(VGA_riscv64)
// riscv64
/* return 1 if success, 0 if failure */
UWord do_acasW ( UWord* addr, UWord expected, UWord nyu )
{
UWord success;
UWord block[3] = { (UWord)addr, nyu, expected};
__asm__ __volatile__(
"ld t0, 0(%1)" "\n\t"
"ld t2, 16(%1)" "\n\t"
"ld t3, 8(%1)" "\n\t"
"lr.d t1, 0(t0)" "\n\t"
"bne t1, t2, 1f" "\n\t"
"sc.d t1, t3, 0(t0)" "\n\t"
"xori %0, t1, 1" "\n\t"
"j 2f" "\n\t"
"1:" "\n\t"
"mv %0, zero" "\n\t"
"2:" "\n\t"
: /*out*/ "=r"(success)
: /*in*/ "r"(&block[0])
: /*trash*/ "t0", "t1", "t2", "t3", "memory"
);
assert(success == 0 || success == 1);
return success;
}
#endif
void atomic_incW ( UWord* w )

View File

@@ -19,6 +19,7 @@
#undef PLAT_arm64_linux
#undef PLAT_s390x_linux
#undef PLAT_mips32_linux
#undef PLAT_riscv64_linux
#undef PLAT_x86_solaris
#undef PLAT_amd64_solaris
@@ -50,6 +51,8 @@
# define PLAT_mips32_linux 1
#elif defined(__linux__) && defined(__nanomips__)
# define PLAT_nanomips_linux 1
#elif defined(__linux__) && defined(__riscv) && (__riscv_xlen == 64)
# define PLAT_riscv64_linux 1
#elif defined(__sun__) && defined(__i386__)
# define PLAT_x86_solaris 1
#elif defined(__sun__) && defined(__x86_64__)
@@ -134,6 +137,13 @@
: /*out*/ : /*in*/ "r"(&(_lval)) \
: /*trash*/ "$t0", "$t1", "memory" \
)
#elif defined(PLAT_riscv64_linux)
# define INC(_lval,_lqual) \
__asm__ __volatile__ ( \
" amoadd.w zero, %1, (%0)\n" \
: /*out*/ : /*in*/ "r"(&(_lval)), "r"(1) \
: /*trash*/ "memory" \
)
#else
# error "Fix Me for this platform"
#endif

View File

@@ -36,6 +36,7 @@
#undef PLAT_s390x_linux
#undef PLAT_mips32_linux
#undef PLAT_mips64_linux
#undef PLAT_riscv64_linux
#undef PLAT_x86_solaris
#undef PLAT_amd64_solaris
@@ -71,6 +72,8 @@
#endif
#elif defined(__linux__) && defined(__nanomips__)
# define PLAT_nanomips_linux 1
#elif defined(__linux__) && defined(__riscv) && (__riscv_xlen == 64)
# define PLAT_riscv64_linux 1
#elif defined(__sun__) && defined(__i386__)
# define PLAT_x86_solaris 1
#elif defined(__sun__) && defined(__x86_64__)
@@ -154,6 +157,13 @@
: /*out*/ : /*in*/ "r"(&(_lval)) \
: /*trash*/ "$t0", "$t1", "memory" \
)
#elif defined(PLAT_riscv64_linux)
# define INC(_lval,_lqual) \
__asm__ __volatile__ ( \
" amoadd.w zero, %1, (%0)\n" \
: /*out*/ : /*in*/ "r"(&(_lval)), "r"(1) \
: /*trash*/ "memory" \
)
#else
# error "Fix Me for this platform"
#endif

View File

@@ -21,6 +21,7 @@
#undef PLAT_arm_linux
#undef PLAT_s390x_linux
#undef PLAT_mips32_linux
#undef PLAT_riscv64_linux
#undef PLAT_x86_solaris
#undef PLAT_amd64_solaris
@@ -52,6 +53,8 @@
# define PLAT_mips32_linux 1
#elif defined(__linux__) && defined(__nanomips__)
# define PLAT_nanomips_linux 1
#elif defined(__linux__) && defined(__riscv) && (__riscv_xlen == 64)
# define PLAT_riscv64_linux 1
#elif defined(__sun__) && defined(__i386__)
# define PLAT_x86_solaris 1
#elif defined(__sun__) && defined(__x86_64__)
@@ -128,7 +131,8 @@
#elif defined(PLAT_ppc32_linux) || defined(PLAT_ppc64_linux) \
|| defined(PLAT_arm_linux) || defined(PLAT_arm64_linux) \
|| defined(PLAT_arm64_freebsd)
|| defined(PLAT_arm64_freebsd) \
|| defined(PLAT_riscv64_linux)
# if defined(HAVE_BUILTIN_ATOMIC)
# define XCHG_M_R(_addr,_lval) \
do { \

View File

@@ -53,6 +53,9 @@ endif
if VGCONF_PLATFORMS_INCLUDE_ARM64_LINUX
SUBDIRS += arm64-linux
endif
if VGCONF_PLATFORMS_INCLUDE_RISCV64_LINUX
SUBDIRS += riscv64-linux
endif
if VGCONF_PLATFORMS_INCLUDE_X86_SOLARIS
SUBDIRS += x86-solaris
endif
@@ -67,7 +70,7 @@ SUBDIRS += amd64-freebsd
endif
DIST_SUBDIRS = x86 amd64 arm64 ppc32 ppc64 s390x linux \
darwin solaris x86-linux amd64-linux arm64-linux \
darwin solaris x86-linux amd64-linux arm64-linux riscv64-linux \
x86-solaris amd64-solaris mips32 mips64 \
freebsd amd64-freebsd x86-freebsd \
common .

View File

@@ -245,6 +245,26 @@ __attribute__((noinline)) void atomic_add_8bit ( char* p, int n )
);
} while (block[2] != 1);
#endif
#elif defined(VGA_riscv64)
unsigned long long int block[3]
= { (unsigned long long int)p, (unsigned long long int)n,
0xFFFFFFFFFFFFFFFFULL};
do {
__asm__ __volatile__(
"mv t0, %0" "\n\t"
"ld t1, (t0)" "\n\t" // p
"ld t2, 8(t0)" "\n\t" // n
"lr.w t3, (t1)" "\n\t"
"slli t3, t3, 56" "\n\t" // sign-extend
"srai t3, t3, 56" "\n\t"
"add t3, t3, t2" "\n\t"
"sc.w t4, t3, (t1)" "\n\t"
"sd t4, 16(t0)" "\n\t"
: /*out*/
: /*in*/ "r"(&block[0])
: /*trash*/ "memory", "t0", "t1", "t2", "t3", "t4"
);
} while (block[2] != 0);
#else
# error "Unsupported arch"
#endif
@@ -461,6 +481,26 @@ __attribute__((noinline)) void atomic_add_16bit ( short* p, int n )
);
} while (block[2] != 1);
#endif
#elif defined(VGA_riscv64)
unsigned long long int block[3]
= { (unsigned long long int)p, (unsigned long long int)n,
0xFFFFFFFFFFFFFFFFULL};
do {
__asm__ __volatile__(
"mv t0, %0" "\n\t"
"ld t1, (t0)" "\n\t" // p
"ld t2, 8(t0)" "\n\t" // n
"lr.w t3, (t1)" "\n\t"
"slli t3, t3, 48" "\n\t" // sign-extend
"srai t3, t3, 48" "\n\t"
"add t3, t3, t2" "\n\t"
"sc.w t4, t3, (t1)" "\n\t"
"sd t4, 16(t0)" "\n\t"
: /*out*/
: /*in*/ "r"(&block[0])
: /*trash*/ "memory", "t0", "t1", "t2", "t3", "t4"
);
} while (block[2] != 0);
#else
# error "Unsupported arch"
#endif
@@ -616,6 +656,24 @@ __attribute__((noinline)) void atomic_add_32bit ( int* p, int n )
: /*trash*/ "memory", "t0", "t1", "t2", "t3"
);
} while (block[2] != 1);
#elif defined(VGA_riscv64)
unsigned long long int block[3]
= { (unsigned long long int)p, (unsigned long long int)n,
0xFFFFFFFFFFFFFFFFULL};
do {
__asm__ __volatile__(
"mv t0, %0" "\n\t"
"ld t1, (t0)" "\n\t" // p
"ld t2, 8(t0)" "\n\t" // n
"lr.w t3, (t1)" "\n\t"
"add t3, t3, t2" "\n\t"
"sc.w t4, t3, (t1)" "\n\t"
"sd t4, 16(t0)" "\n\t"
: /*out*/
: /*in*/ "r"(&block[0])
: /*trash*/ "memory", "t0", "t1", "t2", "t3", "t4"
);
} while (block[2] != 0);
#else
# error "Unsupported arch"
#endif
@@ -718,6 +776,24 @@ __attribute__((noinline)) void atomic_add_64bit ( long long int* p, int n )
: /*trash*/ "memory", "t0", "t1", "t2", "t3"
);
} while (block[2] != 1);
#elif defined(VGA_riscv64)
unsigned long long int block[3]
= { (unsigned long long int)p, (unsigned long long int)n,
0xFFFFFFFFFFFFFFFFULL};
do {
__asm__ __volatile__(
"mv t0, %0" "\n\t"
"ld t1, (t0)" "\n\t" // p
"ld t2, 8(t0)" "\n\t" // n
"lr.d t3, (t1)" "\n\t"
"add t3, t3, t2" "\n\t"
"sc.d t4, t3, (t1)" "\n\t"
"sd t4, 16(t0)" "\n\t"
: /*out*/
: /*in*/ "r"(&block[0])
: /*trash*/ "memory", "t0", "t1", "t2", "t3", "t4"
);
} while (block[2] != 0);
#else
# error "Unsupported arch"
#endif
@@ -731,7 +807,7 @@ __attribute__((noinline)) void atomic_add_128bit ( MyU128* p,
|| defined(VGA_amd64) \
|| defined(VGA_ppc64be) || defined(VGA_ppc64le) \
|| defined(VGA_arm) \
|| defined(VGA_s390x)
|| defined(VGA_s390x) || defined(VGA_riscv64)
/* do nothing; is not supported */
#elif defined(VGA_arm64)
unsigned long long int block[3]

View File

@@ -183,6 +183,23 @@ extern UWord do_syscall_WRK (
return out;
}
#elif defined(VGP_riscv64_linux)
extern UWord do_syscall_WRK (
UWord a1, UWord a2, UWord a3,
UWord a4, UWord a5, UWord a6,
UWord syscall_no
);
asm(
".text\n"
".globl do_syscall_WRK\n"
"do_syscall_WRK:\n"
" mv a7, a6\n"
" li a6, 0\n"
" ecall\n"
" ret\n"
".previous\n"
);
#elif defined(VGP_x86_solaris)
extern ULong
do_syscall_WRK(UWord a1, UWord a2, UWord a3,
@@ -369,7 +386,7 @@ static void non_simd_mprotect (long tid, void* addr, long len)
&err);
if (err)
mprotect_result = -1;
#elif defined(VGP_arm64_linux)
#elif defined(VGP_arm64_linux) || defined(VGP_riscv64_linux)
mprotect_result = do_syscall_WRK((UWord) addr, len, PROT_NONE,
0, 0, 0,
__NR_mprotect);

View File

@@ -14,8 +14,8 @@ To see them, rerun with: --leak-check=full --show-leak-kinds=all
expecting a leak
1,000 bytes in 1 blocks are definitely lost in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-segv-jmp.c:420)
by 0x........: main (leak-segv-jmp.c:495)
by 0x........: f (leak-segv-jmp.c:437)
by 0x........: main (leak-segv-jmp.c:512)
LEAK SUMMARY:
definitely lost: 1,000 bytes in 1 blocks
@@ -30,8 +30,8 @@ mprotect result 0
expecting a leak again
1,000 bytes in 1 blocks are definitely lost in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-segv-jmp.c:420)
by 0x........: main (leak-segv-jmp.c:495)
by 0x........: f (leak-segv-jmp.c:437)
by 0x........: main (leak-segv-jmp.c:512)
LEAK SUMMARY:
definitely lost: 1,000 bytes in 1 blocks
@@ -46,8 +46,8 @@ full mprotect result 0
expecting a leak again after full mprotect
1,000 bytes in 1 blocks are definitely lost in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-segv-jmp.c:420)
by 0x........: main (leak-segv-jmp.c:495)
by 0x........: f (leak-segv-jmp.c:437)
by 0x........: main (leak-segv-jmp.c:512)
LEAK SUMMARY:
definitely lost: 1,000 bytes in 1 blocks
@@ -62,13 +62,13 @@ mprotect result 0
expecting heuristic not to crash after full mprotect
1,000 bytes in 1 blocks are definitely lost in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-segv-jmp.c:420)
by 0x........: main (leak-segv-jmp.c:495)
by 0x........: f (leak-segv-jmp.c:437)
by 0x........: main (leak-segv-jmp.c:512)
200,000 bytes in 1 blocks are possibly lost in loss record ... of ...
at 0x........: calloc (vg_replace_malloc.c:...)
by 0x........: f (leak-segv-jmp.c:467)
by 0x........: main (leak-segv-jmp.c:495)
by 0x........: f (leak-segv-jmp.c:484)
by 0x........: main (leak-segv-jmp.c:512)
LEAK SUMMARY:
definitely lost: 1,000 bytes in 1 blocks

View File

@@ -181,6 +181,11 @@
__asm__ __volatile__ ("mov x17, 0\n\t"); \
__asm__ __volatile__ ("mov x18, 0\n\t"); \
} while (0)
#elif defined(__riscv)
#define CLEAR_CALLER_SAVED_REGS \
do { \
__asm__ __volatile__( "li a0, 0" : : :/*trash*/"a0" ); \
} while (0)
#else
#define CLEAR_CALLER_SAVED_REGS /*nothing*/
#endif

View File

@@ -35,6 +35,9 @@ endif
if VGCONF_ARCHS_INCLUDE_NANOMIPS
SUBDIRS += nanomips
endif
if VGCONF_ARCHS_INCLUDE_RISCV64
SUBDIRS += riscv64
endif
# OS-specific tests
@@ -75,8 +78,9 @@ SUBDIRS += x86-freebsd
endif
DIST_SUBDIRS = x86 amd64 ppc32 ppc64 arm arm64 s390x mips32 mips64 nanomips \
linux darwin solaris freebsd amd64-linux x86-linux amd64-darwin \
x86-darwin amd64-solaris x86-solaris x86-freebsd scripts .
riscv64 linux darwin solaris freebsd amd64-linux x86-linux \
amd64-darwin x86-darwin amd64-solaris x86-solaris x86-freebsd \
scripts .
dist_noinst_SCRIPTS = \
filter_cmdline0 \
@@ -401,6 +405,11 @@ libvex_test_CFLAGS = $(AM_CFLAGS) @FLAG_FSANITIZE@
libvex_test_LDADD = ../../VEX/libvex-@VGCONF_ARCH_PRI@-@VGCONF_OS@.a \
@LIB_UBSAN@
libvexmultiarch_test_CFLAGS= $(AM_CFLAGS) @FLAG_FSANITIZE@
if VGCONF_ARCHS_INCLUDE_RISCV64
# Disable RISC-V linker relaxation, it takes GNU ld 2.39 tens of minutes to sort
# it through on this large test.
libvexmultiarch_test_LDFLAGS = -Wl,--no-relax
endif
libvexmultiarch_test_LDADD = \
../../VEX/libvexmultiarch-@VGCONF_ARCH_PRI@-@VGCONF_OS@.a \
../../VEX/libvex-@VGCONF_ARCH_PRI@-@VGCONF_OS@.a @LIB_UBSAN@

View File

@@ -34,5 +34,6 @@ pair s390x_unexisting_in_32bits s390x
pair arm arm64
pair mips32 mips64
pair nanomips nanoMIPS_unexisting_in_64bits
pair riscv_unexisting_in_32bits riscv64
exit 0

View File

@@ -11,7 +11,7 @@
#include "../../config.h"
/* Division by zero triggers a SIGFPE on x86 and x86_64,
but not on the PowerPC architecture.
but not on the PowerPC, AArch64 and RISC-V architectures.
On ARM-Linux, we do get a SIGFPE, but not from the faulting of a
division instruction (there isn't any such thing) but rather
@@ -19,7 +19,7 @@
Hence we get a SIGFPE but the SI_CODE is different from that on
x86/amd64-linux.
*/
#if defined(__powerpc__) || defined(__aarch64__)
#if defined(__powerpc__) || defined(__aarch64__) || defined(__riscv)
# define DIVISION_BY_ZERO_TRIGGERS_FPE 0
#if defined(VGO_freebsd)
# define DIVISION_BY_ZERO_SI_CODE SI_LWP

View File

@@ -76,6 +76,8 @@ __attribute__((noinline)) static void get_guest_arch(VexArch *ga)
*ga = VexArchMIPS64;
#elif defined(VGA_nanomips)
*ga = VexArchNANOMIPS;
#elif defined(VGA_riscv64)
*ga = VexArchRISCV64;
#else
missing arch;
#endif
@@ -113,6 +115,7 @@ static VexEndness arch_endness (VexArch va) {
else
return VexEndnessBE;
}
case VexArchRISCV64: return VexEndnessLE;
default: failure_exit();
}
}
@@ -139,6 +142,7 @@ static UInt arch_hwcaps (VexArch va) {
case VexArchMIPS64: return VEX_PRID_COMP_MIPS | VEX_MIPS_HOST_FR;
#endif
case VexArchNANOMIPS: return 0;
case VexArchRISCV64: return 0;
default: failure_exit();
}
}
@@ -156,6 +160,7 @@ static Bool mode64 (VexArch va) {
case VexArchMIPS32: return False;
case VexArchMIPS64: return True;
case VexArchNANOMIPS: return False;
case VexArchRISCV64: return True;
default: failure_exit();
}
}
@@ -275,7 +280,7 @@ int main(int argc, char **argv)
// explicitly via command line arguments.
if (multiarch) {
VexArch va;
for (va = VexArchX86; va <= VexArchNANOMIPS; va++) {
for (va = VexArchX86; va <= VexArchRISCV64; va++) {
vta.arch_host = va;
vta.archinfo_host.endness = arch_endness (vta.arch_host);
vta.archinfo_host.hwcaps = arch_hwcaps (vta.arch_host);

View File

@@ -34,6 +34,7 @@ char* all_archs[] = {
"mips32",
"mips64",
"nanomips",
"riscv64",
NULL
};
@@ -79,6 +80,10 @@ static Bool go(char* arch)
#elif defined(VGP_nanomips_linux)
if ( 0 == strcmp( arch, "nanomips" ) ) return True;
#elif defined(VGP_riscv64_linux)
if ( 0 == strcmp( arch, "riscv64" ) ) return True;
#else
# error Unknown platform
#endif // VGP_*

View File

@@ -14,6 +14,7 @@ all_platforms=
all_platforms="$all_platforms x86-linux amd64-linux ppc32-linux ppc64-linux"
all_platforms="$all_platforms arm-linux arm64-linux"
all_platforms="$all_platforms s390x-linux mips32-linux mips64-linux"
all_platforms="$all_platforms riscv64-linux"
all_platforms="$all_platforms x86-darwin amd64-darwin"
all_platforms="$all_platforms x86-solaris amd64-solaris"
all_platforms="$all_platforms x86-freebsd amd64-freebsd"