added boom and torture | added csmith

This commit is contained in:
abejgonzalez 2019-03-08 17:13:08 -08:00
parent 8b899c519d
commit d80acd8cf8
12 changed files with 2541 additions and 1 deletions

6
.gitmodules vendored
View File

@ -19,3 +19,9 @@
[submodule "esp-tools"]
path = toolchains/esp-tools
url = https://github.com/ucb-bar/esp-tools.git
[submodule "tools/torture"]
path = tools/torture
url = git@github.com:ucb-bar/riscv-torture.git
[submodule "generators/boom"]
path = generators/boom
url = git@github.com:riscv-boom/riscv-boom.git

View File

@ -24,6 +24,9 @@ lazy val rocketchip = RootProject(file("generators/rocket-chip"))
lazy val testchipip = (project in file("generators/testchipip")).settings(commonSettings)
.dependsOn(rocketchip)
lazy val boom = (project in file("generators/boom")).settings(commonSettings)
.dependsOn(rocketchip)
// Checks for -DROCKET_USE_MAVEN.
// If it's there, use a maven dependency.
// Else, depend on subprojects in git submodules.

View File

@ -8,7 +8,7 @@ SHELL=/bin/bash
#########################################################################################
lookup_scala_srcs = $(shell find -L $(1)/ -iname "*.scala" 2> /dev/null)
PACKAGES=rocket-chip testchipip
PACKAGES=rocket-chip testchipip boom
SCALA_SOURCES=$(foreach pkg,$(PACKAGES),$(call lookup_scala_srcs,$(base_dir)/generators/$(pkg)/src/main/scala)) $(call lookup_scala_srcs,$(base_dir)/src/main/scala)
#########################################################################################

1
generators/boom Submodule

@ -0,0 +1 @@
Subproject commit c7489137d420b5095a78ab6c64ded56a4581397a

View File

@ -0,0 +1,6 @@
git clone https://github.com/csmith-project/csmith.git
cd csmith
mkdir build
cd build
../configure --prefix=$RISCV
make install

188
scripts/csmith/run-csmith.sh Executable file
View File

@ -0,0 +1,188 @@
# Script to run the csmith random test generator multiple times
TEST_NAME=test
SIM=$1
RUN_AMT=-1
P_INST=1
SEED=-1
WDEBUG_EXT=false
NDEBUG=false
# Make output directory
OUTPUT_DIR=output
SRC_DIR=sources
mkdir -p output
usage(){
echo "run-csmith.sh --sim SIM_BINARY [--run RUN_AMT] [--parallel PARALLEL_INSTANCES] [--seed SEED] [--withdebugext] [--nodebug]"
echo " --sim -s SIM_BINARY is the simulator to test spike against"
echo " --run -r RUN_AMT is the amount of times to run the csmith tests"
echo " defaults to infinity"
echo " --parallel -p PARALLEL_INSTANCES is the amount of instances to spawn in parallel"
echo " defaults to one instance"
echo " --seed -e SEED runs a single test with the seed specified"
echo " ignores all other parameters"
echo " --withdebugext -d run debug version of simulator (used for when"
echo " main sim is not debug version)"
echo " (just appends -debug to sim name)"
echo " --nodebug -n just error when there is a sim mismatch (no vpd)"
}
# Exit everything on one ctrl+c
trap kill_group SIGINT
kill_group(){
echo ""
echo "[ALL] Killing instances."
kill 0
}
# Run the csmith test once
#
# Args:
# $1 instance that this test is running on
# $2 seed to run the test with
run_once () {
BASE_NAME=$OUTPUT_DIR/$TEST_NAME-$1-$2
echo "[$1] Running csmith test with seed=$2"
csmith --seed $2 > $BASE_NAME.c
# Build both a RISCV binary and normal binary
# Test x86-64 first
gcc -I$RISCV/include/csmith-2.4.0 -w $BASE_NAME.c -o $BASE_NAME.bin
timeout 1s ./$BASE_NAME.bin | awk '{print tolower($0)}' > $BASE_NAME.host.out
RV=$?
if [ $RV -ne 0 ]; then
echo "[$1] x86-64 binary timed out. Discard and start over."
rm $BASE_NAME.bin $BASE_NAME.host.out $BASE_NAME.c
return 0
fi
# Test RISCV spike version
riscv64-unknown-elf-gcc -w -I./$SRC_DIR -DPREALLOCATE=1 -mcmodel=medany -static -std=gnu99 -O2 -ffast-math -fno-common -o $BASE_NAME.riscv $BASE_NAME.c $SRC_DIR/syscalls.c $SRC_DIR/crt.S -static -nostdlib -nostartfiles -lm -lgcc -T $SRC_DIR/link.ld -I$RISCV/include/csmith-2.4.0
timeout --foreground 10s spike $BASE_NAME.riscv 1> $BASE_NAME.spike.out 2> $BASE_NAME.spike.log
RV=$?
if [ $RV -ne 0 ]; then
echo "[$1] Spike timed out. Discard and start over."
rm $BASE_NAME.bin $BASE_NAME.host.out $BASE_NAME.c $BASE_NAME.riscv $BASE_NAME.spike.out $BASE_NAME.spike.log
return 0
fi
# Compare x86-64 and Spike
cmp -s $BASE_NAME.spike.out $BASE_NAME.host.out
RV=$?
if [ $RV -ne 0 ]; then
echo "[$1] Spike produces wrong result compared to x86-64 binary. Discard and start over."
rm $BASE_NAME.bin $BASE_NAME.host.out $BASE_NAME.c $BASE_NAME.riscv $BASE_NAME.spike.out $BASE_NAME.spike.log
return 0
fi
# Compare simulator output versus spike
timeout 15m $SIM $BASE_NAME.riscv 1> $BASE_NAME.sim.out
RV=$?
if [ $RV == 124 ]; then
echo "[$1] Simulator timed out. Discard and start over."
rm $BASE_NAME.bin $BASE_NAME.host.out $BASE_NAME.c $BASE_NAME.riscv $BASE_NAME.spike.out $BASE_NAME.spike.log $BASE_NAME.sim.out
return 0
fi
cmp -s $BASE_NAME.sim.out $BASE_NAME.spike.out
RV=$?
if [ $RV -ne 0 ]; then
echo "[$1] Simulator produced wrong result."
if [ $NDEBUG == false ]; then
if [ $WDEBUG_EXT == true ]; then
${SIM}-debug $BASE_NAME.riscv +verbose +vcdplusfile=$BASE_NAME.vpd 1> $BASE_NAME.sim.out 2> $BASE_NAME.sim.log
else
$SIM $BASE_NAME.riscv +verbose +vcdplusfile=$BASE_NAME.vpd 1> $BASE_NAME.sim.out 2> $BASE_NAME.sim.log
fi
echo "[$1] Vpd of error file: $BASE_NAME.vpd"
echo "[$1] Simulator output file: $BASE_NAME.sim.out"
echo "[$1] Simulator log file: $BASE_NAME.sim.log"
fi
kill_group
else
echo "[$1] Simulator and spike agree."
rm $BASE_NAME.bin $BASE_NAME.host.out $BASE_NAME.c $BASE_NAME.riscv $BASE_NAME.spike.out $BASE_NAME.spike.log $BASE_NAME.sim.out
return 0
fi
}
# Run the test for a certain amount of times
# Also setup a random seed
#
# Args:
# $1 instance that this is running on
run() {
if [ $SEED == -1 ]; then
if [ $RUN_AMT == -1 ]; then
while true;
do
SEED=$(od -N 4 -t uL -An /dev/urandom | tr -d " ")
run_once $1 $SEED
done
else
for j in `seq 1 $RUN_AMT`;
do
SEED=$(od -N 4 -t uL -An /dev/urandom | tr -d " ")
run_once $1 $SEED
done
fi
else
run_once $1 $SEED
fi
}
# Parse arguments
while [ "$1" != "" ];
do
case $1 in
-s | --sim ) shift
SIM=$1
;;
-r | --run ) shift
RUN_AMT=$1
;;
-p | --parallel ) shift
P_INST=$1
;;
-e | --seed ) shift
SEED=$1
;;
--withdebugext | -d ) shift
WDEBUG_EXT=true
;;
--nodebug | -n ) shift
NDEBUG=true
;;
-h | --help ) usage
exit 0
esac
shift
done
# Start of script
if [ -z "$SIM" ]; then
echo "Forgot simulator binary."
usage
exit 1
fi
if [ $SEED == -1 ]; then
if [ $RUN_AMT == -1 ]; then
echo "Spawning $P_INST instance(s), running csmith infinite times"
else
echo "Spawning $P_INST instance(s), running csmith $RUN_AMT times"
fi
for i in `seq 1 $P_INST`;
do
run $i &
done
wait
else
RUN_AMT=1
run 1
wait
fi

View File

@ -0,0 +1,237 @@
# See LICENSE for license details.
#include "encoding.h"
#if __riscv_xlen == 64
# define LREG ld
# define SREG sd
# define REGBYTES 8
#else
# define LREG lw
# define SREG sw
# define REGBYTES 4
#endif
.section ".text.init"
.globl _start
_start:
li x1, 0
li x2, 0
li x3, 0
li x4, 0
li x5, 0
li x6, 0
li x7, 0
li x8, 0
li x9, 0
li x10,0
li x11,0
li x12,0
li x13,0
li x14,0
li x15,0
li x16,0
li x17,0
li x18,0
li x19,0
li x20,0
li x21,0
li x22,0
li x23,0
li x24,0
li x25,0
li x26,0
li x27,0
li x28,0
li x29,0
li x30,0
li x31,0
# enable FPU and accelerator if present
li t0, MSTATUS_FS | MSTATUS_XS
csrs mstatus, t0
# make sure XLEN agrees with compilation choice
li t0, 1
slli t0, t0, 31
#if __riscv_xlen == 64
bgez t0, 1f
#else
bltz t0, 1f
#endif
2:
li a0, 1
sw a0, tohost, t0
j 2b
1:
#ifdef __riscv_flen
# initialize FPU if we have one
la t0, 1f
csrw mtvec, t0
fssr x0
fmv.s.x f0, x0
fmv.s.x f1, x0
fmv.s.x f2, x0
fmv.s.x f3, x0
fmv.s.x f4, x0
fmv.s.x f5, x0
fmv.s.x f6, x0
fmv.s.x f7, x0
fmv.s.x f8, x0
fmv.s.x f9, x0
fmv.s.x f10,x0
fmv.s.x f11,x0
fmv.s.x f12,x0
fmv.s.x f13,x0
fmv.s.x f14,x0
fmv.s.x f15,x0
fmv.s.x f16,x0
fmv.s.x f17,x0
fmv.s.x f18,x0
fmv.s.x f19,x0
fmv.s.x f20,x0
fmv.s.x f21,x0
fmv.s.x f22,x0
fmv.s.x f23,x0
fmv.s.x f24,x0
fmv.s.x f25,x0
fmv.s.x f26,x0
fmv.s.x f27,x0
fmv.s.x f28,x0
fmv.s.x f29,x0
fmv.s.x f30,x0
fmv.s.x f31,x0
1:
#endif
# initialize trap vector
la t0, trap_entry
csrw mtvec, t0
# initialize global pointer
.option push
.option norelax
la gp, __global_pointer$
.option pop
la tp, _end + 63
and tp, tp, -64
# get core id
csrr a0, mhartid
# for now, assume only 1 core
li a1, 1
1:bgeu a0, a1, 1b
# give each core 128KB of stack + TLS
#define STKSHIFT 17
sll a2, a0, STKSHIFT
add tp, tp, a2
add sp, a0, 1
sll sp, sp, STKSHIFT
add sp, sp, tp
j _init
.align 2
trap_entry:
addi sp, sp, -272
SREG x1, 1*REGBYTES(sp)
SREG x2, 2*REGBYTES(sp)
SREG x3, 3*REGBYTES(sp)
SREG x4, 4*REGBYTES(sp)
SREG x5, 5*REGBYTES(sp)
SREG x6, 6*REGBYTES(sp)
SREG x7, 7*REGBYTES(sp)
SREG x8, 8*REGBYTES(sp)
SREG x9, 9*REGBYTES(sp)
SREG x10, 10*REGBYTES(sp)
SREG x11, 11*REGBYTES(sp)
SREG x12, 12*REGBYTES(sp)
SREG x13, 13*REGBYTES(sp)
SREG x14, 14*REGBYTES(sp)
SREG x15, 15*REGBYTES(sp)
SREG x16, 16*REGBYTES(sp)
SREG x17, 17*REGBYTES(sp)
SREG x18, 18*REGBYTES(sp)
SREG x19, 19*REGBYTES(sp)
SREG x20, 20*REGBYTES(sp)
SREG x21, 21*REGBYTES(sp)
SREG x22, 22*REGBYTES(sp)
SREG x23, 23*REGBYTES(sp)
SREG x24, 24*REGBYTES(sp)
SREG x25, 25*REGBYTES(sp)
SREG x26, 26*REGBYTES(sp)
SREG x27, 27*REGBYTES(sp)
SREG x28, 28*REGBYTES(sp)
SREG x29, 29*REGBYTES(sp)
SREG x30, 30*REGBYTES(sp)
SREG x31, 31*REGBYTES(sp)
csrr a0, mcause
csrr a1, mepc
mv a2, sp
jal handle_trap
csrw mepc, a0
# Remain in M-mode after eret
li t0, MSTATUS_MPP
csrs mstatus, t0
LREG x1, 1*REGBYTES(sp)
LREG x2, 2*REGBYTES(sp)
LREG x3, 3*REGBYTES(sp)
LREG x4, 4*REGBYTES(sp)
LREG x5, 5*REGBYTES(sp)
LREG x6, 6*REGBYTES(sp)
LREG x7, 7*REGBYTES(sp)
LREG x8, 8*REGBYTES(sp)
LREG x9, 9*REGBYTES(sp)
LREG x10, 10*REGBYTES(sp)
LREG x11, 11*REGBYTES(sp)
LREG x12, 12*REGBYTES(sp)
LREG x13, 13*REGBYTES(sp)
LREG x14, 14*REGBYTES(sp)
LREG x15, 15*REGBYTES(sp)
LREG x16, 16*REGBYTES(sp)
LREG x17, 17*REGBYTES(sp)
LREG x18, 18*REGBYTES(sp)
LREG x19, 19*REGBYTES(sp)
LREG x20, 20*REGBYTES(sp)
LREG x21, 21*REGBYTES(sp)
LREG x22, 22*REGBYTES(sp)
LREG x23, 23*REGBYTES(sp)
LREG x24, 24*REGBYTES(sp)
LREG x25, 25*REGBYTES(sp)
LREG x26, 26*REGBYTES(sp)
LREG x27, 27*REGBYTES(sp)
LREG x28, 28*REGBYTES(sp)
LREG x29, 29*REGBYTES(sp)
LREG x30, 30*REGBYTES(sp)
LREG x31, 31*REGBYTES(sp)
addi sp, sp, 272
mret
.section ".tdata.begin"
.globl _tdata_begin
_tdata_begin:
.section ".tdata.end"
.globl _tdata_end
_tdata_end:
.section ".tbss.end"
.globl _tbss_end
_tbss_end:
.section ".tohost","aw",@progbits
.align 6
.globl tohost
tohost: .dword 0
.align 6
.globl fromhost
fromhost: .dword 0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,66 @@
/*======================================================================*/
/* Proxy kernel linker script */
/*======================================================================*/
/* This is the linker script used when building the proxy kernel. */
/*----------------------------------------------------------------------*/
/* Setup */
/*----------------------------------------------------------------------*/
/* The OUTPUT_ARCH command specifies the machine architecture where the
argument is one of the names used in the BFD library. More
specifically one of the entires in bfd/cpu-mips.c */
OUTPUT_ARCH( "riscv" )
ENTRY(_start)
/*----------------------------------------------------------------------*/
/* Sections */
/*----------------------------------------------------------------------*/
SECTIONS
{
/* text: test code section */
. = 0x80000000;
.text.init : { *(.text.init) }
. = ALIGN(0x1000);
.tohost : { *(.tohost) }
.text : { *(.text) }
/* data segment */
.data : { *(.data) }
.sdata : {
__global_pointer$ = . + 0x800;
*(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*)
*(.sdata .sdata.* .gnu.linkonce.s.*)
}
/* bss segment */
.sbss : {
*(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.scommon)
}
.bss : { *(.bss) }
/* thread-local data segment */
.tdata :
{
_tls_data = .;
*(.tdata.begin)
*(.tdata)
*(.tdata.end)
}
.tbss :
{
*(.tbss)
*(.tbss.end)
}
/* End of uninitalized data segement */
_end = .;
}

View File

@ -0,0 +1,471 @@
// See LICENSE for license details.
#include <stdint.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <limits.h>
#include <sys/signal.h>
#include "util.h"
#define SYS_write 64
#undef strcmp
extern volatile uint64_t tohost;
extern volatile uint64_t fromhost;
static uintptr_t syscall(uintptr_t which, uint64_t arg0, uint64_t arg1, uint64_t arg2)
{
volatile uint64_t magic_mem[8] __attribute__((aligned(64)));
magic_mem[0] = which;
magic_mem[1] = arg0;
magic_mem[2] = arg1;
magic_mem[3] = arg2;
__sync_synchronize();
tohost = (uintptr_t)magic_mem;
while (fromhost == 0)
;
fromhost = 0;
__sync_synchronize();
return magic_mem[0];
}
#define NUM_COUNTERS 2
static uintptr_t counters[NUM_COUNTERS];
static char* counter_names[NUM_COUNTERS];
void setStats(int enable)
{
int i = 0;
#define READ_CTR(name) do { \
while (i >= NUM_COUNTERS) ; \
uintptr_t csr = read_csr(name); \
if (!enable) { csr -= counters[i]; counter_names[i] = #name; } \
counters[i++] = csr; \
} while (0)
READ_CTR(mcycle);
READ_CTR(minstret);
#undef READ_CTR
}
void __attribute__((noreturn)) tohost_exit(uintptr_t code)
{
tohost = (code << 1) | 1;
while (1);
}
uintptr_t __attribute__((weak)) handle_trap(uintptr_t cause, uintptr_t epc, uintptr_t regs[32])
{
tohost_exit(1337);
}
void exit(int code)
{
tohost_exit(code);
}
void abort()
{
exit(128 + SIGABRT);
}
void printstr(const char* s)
{
syscall(SYS_write, 1, (uintptr_t)s, strlen(s));
}
void __attribute__((weak)) thread_entry(int cid, int nc)
{
// multi-threaded programs override this function.
// for the case of single-threaded programs, only let core 0 proceed.
while (cid != 0);
}
int __attribute__((weak)) main(int argc, char** argv)
{
// single-threaded programs override this function.
printstr("Implement main(), foo!\n");
return -1;
}
static void init_tls()
{
register void* thread_pointer asm("tp");
extern char _tls_data;
extern __thread char _tdata_begin, _tdata_end, _tbss_end;
size_t tdata_size = &_tdata_end - &_tdata_begin;
memcpy(thread_pointer, &_tls_data, tdata_size);
size_t tbss_size = &_tbss_end - &_tdata_end;
memset(thread_pointer + tdata_size, 0, tbss_size);
}
void _init(int cid, int nc)
{
init_tls();
thread_entry(cid, nc);
// only single-threaded programs should ever get here.
int ret = main(0, 0);
char buf[NUM_COUNTERS * 32] __attribute__((aligned(64)));
char* pbuf = buf;
for (int i = 0; i < NUM_COUNTERS; i++)
if (counters[i])
pbuf += sprintf(pbuf, "%s = %d\n", counter_names[i], counters[i]);
if (pbuf != buf)
printstr(buf);
exit(ret);
}
#undef putchar
int putchar(int ch)
{
static __thread char buf[64] __attribute__((aligned(64)));
static __thread int buflen = 0;
buf[buflen++] = ch;
if (ch == '\n' || buflen == sizeof(buf))
{
syscall(SYS_write, 1, (uintptr_t)buf, buflen);
buflen = 0;
}
return 0;
}
void printhex(uint64_t x)
{
char str[17];
int i;
for (i = 0; i < 16; i++)
{
str[15-i] = (x & 0xF) + ((x & 0xF) < 10 ? '0' : 'a'-10);
x >>= 4;
}
str[16] = 0;
printstr(str);
}
static inline void printnum(void (*putch)(int, void**), void **putdat,
unsigned long long num, unsigned base, int width, int padc)
{
unsigned digs[sizeof(num)*CHAR_BIT];
int pos = 0;
while (1)
{
digs[pos++] = num % base;
if (num < base)
break;
num /= base;
}
while (width-- > pos)
putch(padc, putdat);
while (pos-- > 0)
putch(digs[pos] + (digs[pos] >= 10 ? 'a' - 10 : '0'), putdat);
}
static unsigned long long getuint(va_list *ap, int lflag)
{
if (lflag >= 2)
return va_arg(*ap, unsigned long long);
else if (lflag)
return va_arg(*ap, unsigned long);
else
return va_arg(*ap, unsigned int);
}
static long long getint(va_list *ap, int lflag)
{
if (lflag >= 2)
return va_arg(*ap, long long);
else if (lflag)
return va_arg(*ap, long);
else
return va_arg(*ap, int);
}
static void vprintfmt(void (*putch)(int, void**), void **putdat, const char *fmt, va_list ap)
{
register const char* p;
const char* last_fmt;
register int ch, err;
unsigned long long num;
int base, lflag, width, precision, altflag;
char padc;
while (1) {
while ((ch = *(unsigned char *) fmt) != '%') {
if (ch == '\0')
return;
fmt++;
putch(ch, putdat);
}
fmt++;
// Process a %-escape sequence
last_fmt = fmt;
padc = ' ';
width = -1;
precision = -1;
lflag = 0;
altflag = 0;
reswitch:
switch (ch = *(unsigned char *) fmt++) {
// flag to pad on the right
case '-':
padc = '-';
goto reswitch;
// flag to pad with 0's instead of spaces
case '0':
padc = '0';
goto reswitch;
// width field
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
for (precision = 0; ; ++fmt) {
precision = precision * 10 + ch - '0';
ch = *fmt;
if (ch < '0' || ch > '9')
break;
}
goto process_precision;
case '*':
precision = va_arg(ap, int);
goto process_precision;
case '.':
if (width < 0)
width = 0;
goto reswitch;
case '#':
altflag = 1;
goto reswitch;
process_precision:
if (width < 0)
width = precision, precision = -1;
goto reswitch;
// long flag (doubled for long long)
case 'l':
lflag++;
goto reswitch;
// character
case 'c':
putch(va_arg(ap, int), putdat);
break;
// string
case 's':
if ((p = va_arg(ap, char *)) == NULL)
p = "(null)";
if (width > 0 && padc != '-')
for (width -= strnlen(p, precision); width > 0; width--)
putch(padc, putdat);
for (; (ch = *p) != '\0' && (precision < 0 || --precision >= 0); width--) {
putch(ch, putdat);
p++;
}
for (; width > 0; width--)
putch(' ', putdat);
break;
// (signed) decimal
case 'd':
num = getint(&ap, lflag);
if ((long long) num < 0) {
putch('-', putdat);
num = -(long long) num;
}
base = 10;
goto signed_number;
// unsigned decimal
case 'u':
base = 10;
goto unsigned_number;
// (unsigned) octal
case 'o':
// should do something with padding so it's always 3 octits
base = 8;
goto unsigned_number;
// pointer
case 'p':
static_assert(sizeof(long) == sizeof(void*));
lflag = 1;
putch('0', putdat);
putch('x', putdat);
/* fall through to 'x' */
// (unsigned) hexadecimal
case 'X':
case 'x':
base = 16;
unsigned_number:
num = getuint(&ap, lflag);
signed_number:
printnum(putch, putdat, num, base, width, padc);
break;
// escaped '%' character
case '%':
putch(ch, putdat);
break;
// unrecognized escape sequence - just print it literally
default:
putch('%', putdat);
fmt = last_fmt;
break;
}
}
}
int printf(const char* fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vprintfmt((void*)putchar, 0, fmt, ap);
va_end(ap);
return 0; // incorrect return value, but who cares, anyway?
}
int sprintf(char* str, const char* fmt, ...)
{
va_list ap;
char* str0 = str;
va_start(ap, fmt);
void sprintf_putch(int ch, void** data)
{
char** pstr = (char**)data;
**pstr = ch;
(*pstr)++;
}
vprintfmt(sprintf_putch, (void**)&str, fmt, ap);
*str = 0;
va_end(ap);
return str - str0;
}
void* memcpy(void* dest, const void* src, size_t len)
{
if ((((uintptr_t)dest | (uintptr_t)src | len) & (sizeof(uintptr_t)-1)) == 0) {
const uintptr_t* s = src;
uintptr_t *d = dest;
while (d < (uintptr_t*)(dest + len))
*d++ = *s++;
} else {
const char* s = src;
char *d = dest;
while (d < (char*)(dest + len))
*d++ = *s++;
}
return dest;
}
void* memset(void* dest, int byte, size_t len)
{
if ((((uintptr_t)dest | len) & (sizeof(uintptr_t)-1)) == 0) {
uintptr_t word = byte & 0xFF;
word |= word << 8;
word |= word << 16;
word |= word << 16 << 16;
uintptr_t *d = dest;
while (d < (uintptr_t*)(dest + len))
*d++ = word;
} else {
char *d = dest;
while (d < (char*)(dest + len))
*d++ = byte;
}
return dest;
}
size_t strlen(const char *s)
{
const char *p = s;
while (*p)
p++;
return p - s;
}
size_t strnlen(const char *s, size_t n)
{
const char *p = s;
while (n-- && *p)
p++;
return p - s;
}
int strcmp(const char* s1, const char* s2)
{
unsigned char c1, c2;
do {
c1 = *s1++;
c2 = *s2++;
} while (c1 != 0 && c1 == c2);
return c1 - c2;
}
char* strcpy(char* dest, const char* src)
{
char* d = dest;
while ((*d++ = *src++))
;
return dest;
}
long atol(const char* str)
{
long res = 0;
int sign = 0;
while (*str == ' ')
str++;
if (*str == '-' || *str == '+') {
sign = *str == '-';
str++;
}
while (*str) {
res *= 10;
res += *str++ - '0';
}
return sign ? -res : res;
}

View File

@ -0,0 +1,90 @@
// See LICENSE for license details.
#ifndef __UTIL_H
#define __UTIL_H
extern void setStats(int enable);
#include <stdint.h>
#define static_assert(cond) switch(0) { case 0: case !!(long)(cond): ; }
static int verify(int n, const volatile int* test, const int* verify)
{
int i;
// Unrolled for faster verification
for (i = 0; i < n/2*2; i+=2)
{
int t0 = test[i], t1 = test[i+1];
int v0 = verify[i], v1 = verify[i+1];
if (t0 != v0) return i+1;
if (t1 != v1) return i+2;
}
if (n % 2 != 0 && test[n-1] != verify[n-1])
return n;
return 0;
}
static int verifyDouble(int n, const volatile double* test, const double* verify)
{
int i;
// Unrolled for faster verification
for (i = 0; i < n/2*2; i+=2)
{
double t0 = test[i], t1 = test[i+1];
double v0 = verify[i], v1 = verify[i+1];
int eq1 = t0 == v0, eq2 = t1 == v1;
if (!(eq1 & eq2)) return i+1+eq1;
}
if (n % 2 != 0 && test[n-1] != verify[n-1])
return n;
return 0;
}
static void __attribute__((noinline)) barrier(int ncores)
{
static volatile int sense;
static volatile int count;
static __thread int threadsense;
__sync_synchronize();
threadsense = !threadsense;
if (__sync_fetch_and_add(&count, 1) == ncores-1)
{
count = 0;
sense = threadsense;
}
else while(sense != threadsense)
;
__sync_synchronize();
}
static uint64_t lfsr(uint64_t x)
{
uint64_t bit = (x ^ (x >> 1)) & 1;
return (x >> 1) | (bit << 62);
}
static uintptr_t insn_len(uintptr_t pc)
{
return (*(unsigned short*)pc & 3) ? 4 : 2;
}
#ifdef __riscv
#include "encoding.h"
#endif
#define stringify_1(s) #s
#define stringify(s) stringify_1(s)
#define stats(code, iter) do { \
unsigned long _c = -read_csr(mcycle), _i = -read_csr(minstret); \
code; \
_c += read_csr(mcycle), _i += read_csr(minstret); \
if (cid == 0) \
printf("\n%s: %ld cycles, %ld.%ld cycles/iter, %ld.%ld CPI\n", \
stringify(code), _c, _c/iter, 10*_c/iter%10, _c/_i, 10*_c/_i%10); \
} while(0)
#endif //__UTIL_H

1
tools/torture Submodule

@ -0,0 +1 @@
Subproject commit 59b0f0f224ff4f1eb6ebb1b4dd7eaf1ab3fac2e5