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 )
#undef PLAT_arm64_linux
#undef PLAT_s390x_linux
#undef PLAT_mips32_linux
+#undef PLAT_riscv64_linux
#undef PLAT_x86_solaris
#undef PLAT_amd64_solaris
# 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__)
: /*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
#undef PLAT_s390x_linux
#undef PLAT_mips32_linux
#undef PLAT_mips64_linux
+#undef PLAT_riscv64_linux
#undef PLAT_x86_solaris
#undef PLAT_amd64_solaris
#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__)
: /*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
#undef PLAT_arm_linux
#undef PLAT_s390x_linux
#undef PLAT_mips32_linux
+#undef PLAT_riscv64_linux
#undef PLAT_x86_solaris
#undef PLAT_amd64_solaris
# 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__)
#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 { \
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
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 .
);
} 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
);
} 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
: /*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
: /*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
|| 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]
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,
&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);
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
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
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
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
__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
if VGCONF_ARCHS_INCLUDE_NANOMIPS
SUBDIRS += nanomips
endif
+if VGCONF_ARCHS_INCLUDE_RISCV64
+SUBDIRS += riscv64
+endif
# OS-specific tests
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 \
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@
pair arm arm64
pair mips32 mips64
pair nanomips nanoMIPS_unexisting_in_64bits
+pair riscv_unexisting_in_32bits riscv64
exit 0
#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
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
*ga = VexArchMIPS64;
#elif defined(VGA_nanomips)
*ga = VexArchNANOMIPS;
+#elif defined(VGA_riscv64)
+ *ga = VexArchRISCV64;
#else
missing arch;
#endif
else
return VexEndnessBE;
}
+ case VexArchRISCV64: return VexEndnessLE;
default: failure_exit();
}
}
case VexArchMIPS64: return VEX_PRID_COMP_MIPS | VEX_MIPS_HOST_FR;
#endif
case VexArchNANOMIPS: return 0;
+ case VexArchRISCV64: return 0;
default: failure_exit();
}
}
case VexArchMIPS32: return False;
case VexArchMIPS64: return True;
case VexArchNANOMIPS: return False;
+ case VexArchRISCV64: return True;
default: failure_exit();
}
}
// 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);
"mips32",
"mips64",
"nanomips",
+ "riscv64",
NULL
};
#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_*
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"