vendored riscv-tests

This commit is contained in:
Saad Khalid 2023-01-26 16:03:23 +00:00 committed by Greg Chadwick
parent 15da9f9753
commit 9534627463
446 changed files with 40537 additions and 0 deletions

14
vendor/riscv-tests/.gitignore vendored Normal file
View file

@ -0,0 +1,14 @@
*~
*.riscv
*.host
*.o
*.dump
*.out
*.hex
.*.swp
*.pyc
/autom4te.cache
/Makefile
/config.log
/config.status
/build

3
vendor/riscv-tests/.gitmodules vendored Normal file
View file

@ -0,0 +1,3 @@
[submodule "env"]
path = env
url = https://github.com/riscv/riscv-test-env.git

24
vendor/riscv-tests/LICENSE vendored Normal file
View file

@ -0,0 +1,24 @@
Copyright (c) 2012-2015, The Regents of the University of California (Regents).
All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the Regents nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

45
vendor/riscv-tests/Makefile.in vendored Normal file
View file

@ -0,0 +1,45 @@
prefix := @prefix@
abs_top_src_dir := @abs_top_srcdir@
XLEN := @XLEN@
target_alias := @target_alias@
ifeq ($(target_alias),)
RISCV_PREFIX_VAR :=
else
RISCV_PREFIX_VAR := RISCV_PREFIX=@target_alias@-
endif
instbasedir := $(DESTDIR)$(prefix)
bmarkdir := $(abs_top_src_dir)/benchmarks
isa_src_dir := $(abs_top_src_dir)/isa
debug_src_dir := $(abs_top_src_dir)/debug
all: benchmarks isa
install: all
install -d $(instbasedir)/share/riscv-tests/isa
install -d $(instbasedir)/share/riscv-tests/benchmarks
install -p -m 644 `find isa -maxdepth 1 -type f` $(instbasedir)/share/riscv-tests/isa
install -p -m 644 `find benchmarks -maxdepth 1 -type f` $(instbasedir)/share/riscv-tests/benchmarks
benchmarks:
mkdir -p benchmarks
$(MAKE) -C benchmarks -f $(bmarkdir)/Makefile src_dir=$(bmarkdir) XLEN=$(XLEN) $(RISCV_PREFIX_VAR)
isa:
mkdir -p isa
$(MAKE) -C isa -f $(isa_src_dir)/Makefile src_dir=$(isa_src_dir) XLEN=$(XLEN) $(RISCV_PREFIX_VAR)
debug-check:
mkdir -p debug
$(MAKE) -C debug -f $(debug_src_dir)/Makefile src_dir=$(debug_src_dir) XLEN=$(XLEN)
debug-check-fast:
mkdir -p debug
$(MAKE) -C debug -f $(debug_src_dir)/Makefile src_dir=$(debug_src_dir) XLEN=$(XLEN) spike$(XLEN)
clean:
[ ! -d isa ] || $(MAKE) -C isa -f $(isa_src_dir)/Makefile src_dir=$(isa_src_dir) XLEN=$(XLEN) $(RISCV_PREFIX_VAR) clean
[ ! -d benchmarks ] || $(MAKE) -C benchmarks -f $(bmarkdir)/Makefile src_dir=$(bmarkdir) clean
[ ! -d debug ] || $(MAKE) -C debug -f $(debug_src_dir)/Makefile src_dir=$(debug_src_dir) clean
.PHONY: benchmarks isa clean

177
vendor/riscv-tests/README.md vendored Normal file
View file

@ -0,0 +1,177 @@
riscv-tests
================
About
-----------
This repository hosts unit tests for RISC-V processors.
Building from repository
-----------------------------
We assume that the RISCV environment variable is set to the RISC-V tools
install path, and that the riscv-gnu-toolchain package is installed.
$ git clone https://github.com/riscv/riscv-tests
$ cd riscv-tests
$ git submodule update --init --recursive
$ autoconf
$ ./configure --prefix=$RISCV/target
$ make
$ make install
The rest of this document describes the format of test programs for the RISC-V
architecture.
Test Virtual Machines
-------------------------
To allow maximum reuse of a given test, each test program is constrained to
only use features of a given *test virtual machine* or TVM. A TVM hides
differences between alternative implementations by defining:
* The set of registers and instructions that can be used.
* Which portions of memory can be accessed.
* The way the test program starts and ends execution.
* The way that test data is input.
* The way that test results are output.
The following table shows the TVMs currently defined for RISC-V. All of these
TVMs only support a single hardware thread.
TVM Name | Description
--- | ---
`rv32ui` | RV32 user-level, integer only
`rv32si` | RV32 supervisor-level, integer only
`rv64ui` | RV64 user-level, integer only
`rv64uf` | RV64 user-level, integer and floating-point
`rv64uv` | RV64 user-level, integer, floating-point, and vector
`rv64si` | RV64 supervisor-level, integer only
`rv64sv` | RV64 supervisor-level, integer and vector
A test program for RISC-V is written within a single assembly language file,
which is passed through the C preprocessor, and all regular assembly
directives can be used. An example test program is shown below. Each test
program should first include the `riscv_test.h` header file, which defines the
macros used by the TVM. The header file will have different contents depending
on the target environment for which the test will be built. One of the goals
of the various TVMs is to allow the same test program to be compiled and run
on very different target environments yet still produce the same results. The
following table shows the target environment currently defined.
Target Environment Name | Description
--- | ---
`p` | virtual memory is disabled, only core 0 boots up
`pm` | virtual memory is disabled, all cores boot up
`pt` | virtual memory is disabled, timer interrupt fires every 100 cycles
`v` | virtual memory is enabled
Each test program must next specify for which TVM it is designed by including
the appropriate TVM macro, `RVTEST_RV64U` in this example. This specification
can change the way in which subsequent macros are interpreted, and supports
a static check of the TVM functionality used by the program.
The test program will begin execution at the first instruction after
`RVTEST_CODE_BEGIN`, and continue until execution reaches an `RVTEST_PASS`
macro or the `RVTEST_CODE_END` macro, which is implicitly a success. A test
can explicitly fail by invoking the `RVTEST_FAIL` macro.
The example program contains self-checking code to test the result of the add.
However, self-checks rely on correct functioning of the processor instructions
used to implement the self check (e.g., the branch) and so cannot be the only
testing strategy.
All tests should also contain a test data section, delimited by
`RVTEST_DATA_BEGIN` and `RVTEST_DATA_END`. There is no alignment guarantee for
the start of the test data section, so regular assembler alignment
instructions should be used to ensure desired alignment of data values. This
region of memory will be captured at the end of the test to act as a signature
from the test. The signature can be compared with that from a run on the
golden model.
Any given test environment for running tests should also include a timeout
facility, which will class a test as failing if it does not successfully
complete a test within a reasonable time bound.
#include "riscv_test.h"
RVTEST_RV64U # Define TVM used by program.
# Test code region.
RVTEST_CODE_BEGIN # Start of test code.
lw x2, testdata
addi x2, 1 # Should be 42 into $2.
sw x2, result # Store result into memory overwriting 1s.
li x3, 42 # Desired result.
bne x2, x3, fail # Fail out if doesn't match.
RVTEST_PASS # Signal success.
fail:
RVTEST_FAIL
RVTEST_CODE_END # End of test code.
# Input data section.
# This section is optional, and this data is NOT saved in the output.
.data
.align 3
testdata:
.dword 41
# Output data section.
RVTEST_DATA_BEGIN # Start of test output data region.
.align 3
result:
.dword -1
RVTEST_DATA_END # End of test output data region.
User-Level TVMs
--------------------
Test programs for the `rv32u*` and `rv64u*` TVMs can contain all instructions
from the respective base user-level ISA (RV32 or RV64), except for those with
the SYSTEM major opcode (syscall, break, rdcycle, rdtime, rdinstret). All user
registers (pc, x0-x31, f0-f31, fsr) can be accessed.
The `rv32ui` and `rv64ui` TVMs are integer-only subsets of `rv32u` and `rv64u`
respectively. These subsets can not use any floating-point instructions (major
opcodes: LOAD-FP, STORE-FP, MADD, MSUB, NMSUB, NMADD, OP-FP), and hence cannot
access the floating-point register state (f0-f31 and fsr). The integer-only
TVMs are useful for initial processor bringup and to test simpler
implementations that lack a hardware FPU.
Note that any `rv32ui` test program is also valid for the `rv32u` TVM, and
similarly `rv64ui` is a strict subset of `rv64u`. To allow a given test to run
on the widest possible set of implementations, it is desirable to write any
given test to run on the smallest or least capable TVM possible. For example,
any simple tests of integer functionality should be written for the `rv64ui`
TVM, as the same test can then be run on RV64 implementations with or without a
hardware FPU. As another example, all tests for these base user-level TVMs will
also be valid for more advanced processors with instruction-set extensions.
At the start of execution, the values of all registers are undefined. All
branch and jump destinations must be to labels within the test code region of
the assembler source file. The code and data sections will be relocated
differently for the various implementations of the test environment, and so
test program results shall not depend on absolute addresses of instructions or
data memory. The test build environment should support randomization of the
section relocation to provide better coverage and to ensure test signatures do
not contain absolute addresses.
Supervisor-Level TVMs
--------------------------
The supervisor-level TVMs allow testing of supervisor-level state and
instructions. As with the user-level TVMs, we provide integer-only
supervisor-level TVMs indicated with a trailing `i`.
History and Acknowledgements
---------------------------------
This style of test virtual machine originated with the T0 (Torrent-0) vector
microprocessor project at UC Berkeley and ICSI, begun in 1992. The main
developers of this test strategy were Krste Asanovic and David Johnson. A
precursor to `torture` was `rantor` developed by Phil Kohn at ICSI.
A variant of this testing approach was also used for the Scale vector-thread
processor at MIT, begun in 2000. Ronny Krashinsky and Christopher Batten were
the principal architects of the Scale chip. Jeffrey Cohen and Mark Hampton
developed a version of torture capable of generating vector-thread code.

98
vendor/riscv-tests/benchmarks/Makefile vendored Normal file
View file

@ -0,0 +1,98 @@
#=======================================================================
# UCB VLSI FLOW: Makefile for riscv-bmarks
#-----------------------------------------------------------------------
# Yunsup Lee (yunsup@cs.berkeley.edu)
#
XLEN ?= 64
default: all
src_dir = .
instname = riscv-bmarks
instbasedir = $(UCB_VLSI_HOME)/install
#--------------------------------------------------------------------
# Sources
#--------------------------------------------------------------------
bmarks = \
median \
qsort \
rsort \
towers \
vvadd \
multiply \
mm \
dhrystone \
spmv \
mt-vvadd \
mt-matmul \
pmp \
#--------------------------------------------------------------------
# Build rules
#--------------------------------------------------------------------
RISCV_PREFIX ?= riscv$(XLEN)-unknown-elf-
RISCV_GCC ?= $(RISCV_PREFIX)gcc
RISCV_GCC_OPTS ?= -DPREALLOCATE=1 -mcmodel=medany -static -std=gnu99 -O2 -ffast-math -fno-common -fno-builtin-printf -fno-tree-loop-distribute-patterns
RISCV_LINK ?= $(RISCV_GCC) -T $(src_dir)/common/test.ld $(incs)
RISCV_LINK_OPTS ?= -static -nostdlib -nostartfiles -lm -lgcc -T $(src_dir)/common/test.ld
RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump --disassemble-all --disassemble-zeroes --section=.text --section=.text.startup --section=.text.init --section=.data
RISCV_SIM ?= spike --isa=rv$(XLEN)gc
incs += -I$(src_dir)/../env -I$(src_dir)/common $(addprefix -I$(src_dir)/, $(bmarks))
objs :=
define compile_template
$(1).riscv: $(wildcard $(src_dir)/$(1)/*) $(wildcard $(src_dir)/common/*)
$$(RISCV_GCC) $$(incs) $$(RISCV_GCC_OPTS) -o $$@ $(wildcard $(src_dir)/$(1)/*.c) $(wildcard $(src_dir)/common/*.c) $(wildcard $(src_dir)/common/*.S) $$(RISCV_LINK_OPTS)
endef
$(foreach bmark,$(bmarks),$(eval $(call compile_template,$(bmark))))
#------------------------------------------------------------
# Build and run benchmarks on riscv simulator
bmarks_riscv_bin = $(addsuffix .riscv, $(bmarks))
bmarks_riscv_dump = $(addsuffix .riscv.dump, $(bmarks))
bmarks_riscv_out = $(addsuffix .riscv.out, $(bmarks))
$(bmarks_riscv_dump): %.riscv.dump: %.riscv
$(RISCV_OBJDUMP) $< > $@
$(bmarks_riscv_out): %.riscv.out: %.riscv
$(RISCV_SIM) $< > $@
riscv: $(bmarks_riscv_dump)
run: $(bmarks_riscv_out)
junk += $(bmarks_riscv_bin) $(bmarks_riscv_dump) $(bmarks_riscv_hex) $(bmarks_riscv_out)
#------------------------------------------------------------
# Default
all: riscv
#------------------------------------------------------------
# Install
date_suffix = $(shell date +%Y-%m-%d_%H-%M)
install_dir = $(instbasedir)/$(instname)-$(date_suffix)
latest_install = $(shell ls -1 -d $(instbasedir)/$(instname)* | tail -n 1)
install:
mkdir $(install_dir)
cp -r $(bmarks_riscv_bin) $(bmarks_riscv_dump) $(install_dir)
install-link:
rm -rf $(instbasedir)/$(instname)
ln -s $(latest_install) $(instbasedir)/$(instname)
#------------------------------------------------------------
# Clean up
clean:
rm -rf $(objs) $(junk)

View file

@ -0,0 +1,225 @@
# 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
add sp, a0, 1
sll sp, sp, STKSHIFT
add sp, sp, tp
sll a2, a0, STKSHIFT
add tp, tp, a2
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 ".tohost","aw",@progbits
.align 6
.globl tohost
tohost: .dword 0
.align 6
.globl fromhost
fromhost: .dword 0

View file

@ -0,0 +1,469 @@
// 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 _tdata_begin, _tdata_end, _tbss_end;
size_t tdata_size = &_tdata_end - &_tdata_begin;
memcpy(thread_pointer, &_tdata_begin, 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':
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,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) }
. = ALIGN(0x1000);
.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 :
{
_tdata_begin = .;
*(.tdata)
_tdata_end = .;
}
.tbss :
{
*(.tbss)
_tbss_end = .;
}
/* End of uninitalized data segement */
_end = .;
}

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

View file

@ -0,0 +1,185 @@
// See LICENSE for license details.
#pragma GCC optimize ("no-inline")
#include "dhrystone.h"
#ifndef REG
#define REG
/* REG becomes defined as empty */
/* i.e. no register variables */
#else
#undef REG
#define REG register
#endif
extern int Int_Glob;
extern char Ch_1_Glob;
Proc_6 (Enum_Val_Par, Enum_Ref_Par)
/*********************************/
/* executed once */
/* Enum_Val_Par == Ident_3, Enum_Ref_Par becomes Ident_2 */
Enumeration Enum_Val_Par;
Enumeration *Enum_Ref_Par;
{
*Enum_Ref_Par = Enum_Val_Par;
if (! Func_3 (Enum_Val_Par))
/* then, not executed */
*Enum_Ref_Par = Ident_4;
switch (Enum_Val_Par)
{
case Ident_1:
*Enum_Ref_Par = Ident_1;
break;
case Ident_2:
if (Int_Glob > 100)
/* then */
*Enum_Ref_Par = Ident_1;
else *Enum_Ref_Par = Ident_4;
break;
case Ident_3: /* executed */
*Enum_Ref_Par = Ident_2;
break;
case Ident_4: break;
case Ident_5:
*Enum_Ref_Par = Ident_3;
break;
} /* switch */
} /* Proc_6 */
Proc_7 (Int_1_Par_Val, Int_2_Par_Val, Int_Par_Ref)
/**********************************************/
/* executed three times */
/* first call: Int_1_Par_Val == 2, Int_2_Par_Val == 3, */
/* Int_Par_Ref becomes 7 */
/* second call: Int_1_Par_Val == 10, Int_2_Par_Val == 5, */
/* Int_Par_Ref becomes 17 */
/* third call: Int_1_Par_Val == 6, Int_2_Par_Val == 10, */
/* Int_Par_Ref becomes 18 */
One_Fifty Int_1_Par_Val;
One_Fifty Int_2_Par_Val;
One_Fifty *Int_Par_Ref;
{
One_Fifty Int_Loc;
Int_Loc = Int_1_Par_Val + 2;
*Int_Par_Ref = Int_2_Par_Val + Int_Loc;
} /* Proc_7 */
Proc_8 (Arr_1_Par_Ref, Arr_2_Par_Ref, Int_1_Par_Val, Int_2_Par_Val)
/*********************************************************************/
/* executed once */
/* Int_Par_Val_1 == 3 */
/* Int_Par_Val_2 == 7 */
Arr_1_Dim Arr_1_Par_Ref;
Arr_2_Dim Arr_2_Par_Ref;
int Int_1_Par_Val;
int Int_2_Par_Val;
{
REG One_Fifty Int_Index;
REG One_Fifty Int_Loc;
Int_Loc = Int_1_Par_Val + 5;
Arr_1_Par_Ref [Int_Loc] = Int_2_Par_Val;
Arr_1_Par_Ref [Int_Loc+1] = Arr_1_Par_Ref [Int_Loc];
Arr_1_Par_Ref [Int_Loc+30] = Int_Loc;
for (Int_Index = Int_Loc; Int_Index <= Int_Loc+1; ++Int_Index)
Arr_2_Par_Ref [Int_Loc] [Int_Index] = Int_Loc;
Arr_2_Par_Ref [Int_Loc] [Int_Loc-1] += 1;
Arr_2_Par_Ref [Int_Loc+20] [Int_Loc] = Arr_1_Par_Ref [Int_Loc];
Int_Glob = 5;
} /* Proc_8 */
Enumeration Func_1 (Ch_1_Par_Val, Ch_2_Par_Val)
/*************************************************/
/* executed three times */
/* first call: Ch_1_Par_Val == 'H', Ch_2_Par_Val == 'R' */
/* second call: Ch_1_Par_Val == 'A', Ch_2_Par_Val == 'C' */
/* third call: Ch_1_Par_Val == 'B', Ch_2_Par_Val == 'C' */
Capital_Letter Ch_1_Par_Val;
Capital_Letter Ch_2_Par_Val;
{
Capital_Letter Ch_1_Loc;
Capital_Letter Ch_2_Loc;
Ch_1_Loc = Ch_1_Par_Val;
Ch_2_Loc = Ch_1_Loc;
if (Ch_2_Loc != Ch_2_Par_Val)
/* then, executed */
return (Ident_1);
else /* not executed */
{
Ch_1_Glob = Ch_1_Loc;
return (Ident_2);
}
} /* Func_1 */
Boolean Func_2 (Str_1_Par_Ref, Str_2_Par_Ref)
/*************************************************/
/* executed once */
/* Str_1_Par_Ref == "DHRYSTONE PROGRAM, 1'ST STRING" */
/* Str_2_Par_Ref == "DHRYSTONE PROGRAM, 2'ND STRING" */
Str_30 Str_1_Par_Ref;
Str_30 Str_2_Par_Ref;
{
REG One_Thirty Int_Loc;
Capital_Letter Ch_Loc;
Int_Loc = 2;
while (Int_Loc <= 2) /* loop body executed once */
if (Func_1 (Str_1_Par_Ref[Int_Loc],
Str_2_Par_Ref[Int_Loc+1]) == Ident_1)
/* then, executed */
{
Ch_Loc = 'A';
Int_Loc += 1;
} /* if, while */
if (Ch_Loc >= 'W' && Ch_Loc < 'Z')
/* then, not executed */
Int_Loc = 7;
if (Ch_Loc == 'R')
/* then, not executed */
return (true);
else /* executed */
{
if (strcmp (Str_1_Par_Ref, Str_2_Par_Ref) > 0)
/* then, not executed */
{
Int_Loc += 7;
Int_Glob = Int_Loc;
return (true);
}
else /* executed */
return (false);
} /* if Ch_Loc */
} /* Func_2 */
Boolean Func_3 (Enum_Par_Val)
/***************************/
/* executed once */
/* Enum_Par_Val == Ident_3 */
Enumeration Enum_Par_Val;
{
Enumeration Enum_Loc;
Enum_Loc = Enum_Par_Val;
if (Enum_Loc == Ident_3)
/* then, executed */
return (true);
else /* not executed */
return (false);
} /* Func_3 */
void debug_printf(const char* str, ...)
{
}

View file

@ -0,0 +1,477 @@
// See LICENSE for license details.
#ifndef _DHRYSTONE_H
#define _DHRYSTONE_H
/****************** "DHRYSTONE" Benchmark Program ***************************/
#define Version "C, Version 2.2"
/* File: dhry_1.c (part 2 of 3)
* Author: Reinhold P. Weicker
* Siemens Nixdorf, Paderborn/Germany
* weicker@specbench.org
* Date: May 25, 1988
* Modified: Steven Pemberton, CWI, Amsterdam; Steven.Pemberton@cwi.nl
* Date: October, 1993; March 1995
* Included both files into one source, that gets compiled
* in two passes. Made program auto-compiling, and auto-running,
* and generally made it much easier to use.
*
* Original Version (in Ada) published in
* "Communications of the ACM" vol. 27., no. 10 (Oct. 1984),
* pp. 1013 - 1030, together with the statistics
* on which the distribution of statements etc. is based.
*
* In this C version, the following C library functions are used:
* - strcpy, strcmp (inside the measurement loop)
* - printf, scanf (outside the measurement loop)
* In addition, Berkeley UNIX system calls "times ()" or "time ()"
* are used for execution time measurement. For measurements
* on other systems, these calls have to be changed.
*
* Collection of Results:
* Reinhold Weicker (address see above) and
*
* Rick Richardson
* PC Research. Inc.
* 94 Apple Orchard Drive
* Tinton Falls, NJ 07724
* Phone: (201) 389-8963 (9-17 EST)
* Usenet: ...!uunet!pcrat!rick
*
* Please send results to Rick Richardson and/or Reinhold Weicker.
* Complete information should be given on hardware and software used.
* Hardware information includes: Machine type, CPU, type and size
* of caches; for microprocessors: clock frequency, memory speed
* (number of wait states).
* Software information includes: Compiler (and runtime library)
* manufacturer and version, compilation switches, OS version.
* The Operating System version may give an indication about the compiler;
* Dhrystone itself performs no OS calls in the measurement loop.
*
* The complete output generated by the program should be mailed
* such that at least some checks for correctness can be made.
*
***************************************************************************
*
* Defines: The following "Defines" are possible:
* -DREG (default: Not defined)
* As an approximation to what an average C programmer
* might do, causes the "register" storage class to be applied
* - for local variables, if they are used (dynamically)
* five or more times
* - for parameters if they are used (dynamically)
* six or more times
* Note that an optimal "register" strategy is
* compiler-dependent, and that "register" declarations
* do not necessarily lead to faster execution.
* -DNOSTRUCTASSIGN (default: Not defined)
* Define if the C compiler does not support
* assignment of structures.
* -DNOENUMS (default: Not defined)
* Define if the C compiler does not support
* enumeration types.
* -DTIMES (default)
* -DTIME
* The "times" function of UNIX (returning process times)
* or the "time" function (returning wallclock time)
* is used for measurement.
* For single user machines, "time ()" is adequate. For
* multi-user machines where you cannot get single-user
* access, use the "times ()" function. If you have
* neither, use a stopwatch in the dead of night.
* "printf"s are provided marking the points "Start Timer"
* and "Stop Timer". DO NOT use the UNIX "time(1)"
* command, as this will measure the total time to
* run this program, which will (erroneously) include
* the time to allocate storage (malloc) and to perform
* the initialization.
* -DHZ=nnn
* In Berkeley UNIX, the function "times" returns process
* time in 1/HZ seconds, with HZ = 60 for most systems.
* CHECK YOUR SYSTEM DESCRIPTION BEFORE YOU JUST APPLY
* A VALUE.
*
***************************************************************************
*
* History: Version C/2.1 was made for two reasons:
*
* 1) There was an obvious need for a common C version of
* Dhrystone, since C is at present the most popular system
* programming language for the class of processors
* (microcomputers, minicomputers) where Dhrystone is used most.
* There should be, as far as possible, only one C version of
* Dhrystone such that results can be compared without
* restrictions. In the past, the C versions distributed
* by Rick Richardson (Version 1.1) and by Reinhold Weicker
* had small (though not significant) differences.
*
* 2) As far as it is possible without changes to the Dhrystone
* statistics, optimizing compilers should be prevented from
* removing significant statements.
*
* This C version has been developed in cooperation with
* Rick Richardson (Tinton Falls, NJ), it incorporates many
* ideas from the "Version 1.1" distributed previously by
* him over the UNIX network Usenet.
* I also thank Chaim Benedelac (National Semiconductor),
* David Ditzel (SUN), Earl Killian and John Mashey (MIPS),
* Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley)
* for their help with comments on earlier versions of the
* benchmark.
*
* Changes: In the initialization part, this version follows mostly
* Rick Richardson's version distributed via Usenet, not the
* version distributed earlier via floppy disk by Reinhold Weicker.
* As a concession to older compilers, names have been made
* unique within the first 8 characters.
* Inside the measurement loop, this version follows the
* version previously distributed by Reinhold Weicker.
*
* At several places in the benchmark, code has been added,
* but within the measurement loop only in branches that
* are not executed. The intention is that optimizing compilers
* should be prevented from moving code out of the measurement
* loop, or from removing code altogether. Since the statements
* that are executed within the measurement loop have NOT been
* changed, the numbers defining the "Dhrystone distribution"
* (distribution of statements, operand types and locality)
* still hold. Except for sophisticated optimizing compilers,
* execution times for this version should be the same as
* for previous versions.
*
* Since it has proven difficult to subtract the time for the
* measurement loop overhead in a correct way, the loop check
* has been made a part of the benchmark. This does have
* an impact - though a very minor one - on the distribution
* statistics which have been updated for this version.
*
* All changes within the measurement loop are described
* and discussed in the companion paper "Rationale for
* Dhrystone version 2".
*
* Because of the self-imposed limitation that the order and
* distribution of the executed statements should not be
* changed, there are still cases where optimizing compilers
* may not generate code for some statements. To a certain
* degree, this is unavoidable for small synthetic benchmarks.
* Users of the benchmark are advised to check code listings
* whether code is generated for all statements of Dhrystone.
*
* Version 2.1 is identical to version 2.0 distributed via
* the UNIX network Usenet in March 1988 except that it corrects
* some minor deficiencies that were found by users of version 2.0.
* The only change within the measurement loop is that a
* non-executed "else" part was added to the "if" statement in
* Func_3, and a non-executed "else" part removed from Proc_3.
*
* Version C/2.2, Steven Pemberton, October 1993
* Functionally, identical to version 2.2; the changes are in
* how you compile and use it:
* - Everything is in one file now, but compiled in 2 passes
* - Compile (and run) by running the file through the shell: 'sh dhry.c"
* - Uses the system definition of HZ if one can be found
* - HZ must be defined, otherwise it won't compile (no defaults here)
* - The (uninteresting) output is printed to stderr (dhry2 > /dev/null)
* - The number of loops is passed as a parameter, rather than read
* (dhry2 500000)
* - If the number of loops is insufficient to get a good result,
* it repeats it with loops*10 until it is enough (rather than just
* stopping)
* - Output says which sort of clock it is using, and the HZ value
* - You can use -DREG instead of the -DREG=register of previous versions
* - Some stylistic cleanups.
*
***************************************************************************
*
* Compilation model and measurement (IMPORTANT):
*
* The following "ground rules" apply for measurements:
* - Separate compilation
* - No procedure merging
* - Otherwise, compiler optimizations are allowed but should be indicated
* - Default results are those without register declarations
* See the companion paper "Rationale for Dhrystone Version 2" for a more
* detailed discussion of these ground rules.
*
* For 16-Bit processors (e.g. 80186, 80286), times for all compilation
* models ("small", "medium", "large" etc.) should be given if possible,
* together with a definition of these models for the compiler system used.
*
**************************************************************************
*
* Dhrystone (C version) statistics:
*
* [Comment from the first distribution, updated for version 2.
* Note that because of language differences, the numbers are slightly
* different from the Ada version.]
*
* The following program contains statements of a high level programming
* language (here: C) in a distribution considered representative:
*
* assignments 52 (51.0 %)
* control statements 33 (32.4 %)
* procedure, function calls 17 (16.7 %)
*
* 103 statements are dynamically executed. The program is balanced with
* respect to the three aspects:
*
* - statement type
* - operand type
* - operand locality
* operand global, local, parameter, or constant.
*
* The combination of these three aspects is balanced only approximately.
*
* 1. Statement Type:
* ----------------- number
*
* V1 = V2 9
* (incl. V1 = F(..)
* V = Constant 12
* Assignment, 7
* with array element
* Assignment, 6
* with record component
* --
* 34 34
*
* X = Y +|-|"&&"|"|" Z 5
* X = Y +|-|"==" Constant 6
* X = X +|- 1 3
* X = Y *|/ Z 2
* X = Expression, 1
* two operators
* X = Expression, 1
* three operators
* --
* 18 18
*
* if .... 14
* with "else" 7
* without "else" 7
* executed 3
* not executed 4
* for ... 7 | counted every time
* while ... 4 | the loop condition
* do ... while 1 | is evaluated
* switch ... 1
* break 1
* declaration with 1
* initialization
* --
* 34 34
*
* P (...) procedure call 11
* user procedure 10
* library procedure 1
* X = F (...)
* function call 6
* user function 5
* library function 1
* --
* 17 17
* ---
* 103
*
* The average number of parameters in procedure or function calls
* is 1.82 (not counting the function values aX *
*
* 2. Operators
* ------------
* number approximate
* percentage
*
* Arithmetic 32 50.8
*
* + 21 33.3
* - 7 11.1
* * 3 4.8
* / (int div) 1 1.6
*
* Comparison 27 42.8
*
* == 9 14.3
* /= 4 6.3
* > 1 1.6
* < 3 4.8
* >= 1 1.6
* <= 9 14.3
*
* Logic 4 6.3
*
* && (AND-THEN) 1 1.6
* | (OR) 1 1.6
* ! (NOT) 2 3.2
*
* -- -----
* 63 100.1
*
*
* 3. Operand Type (counted once per operand reference):
* ---------------
* number approximate
* percentage
*
* Integer 175 72.3 %
* Character 45 18.6 %
* Pointer 12 5.0 %
* String30 6 2.5 %
* Array 2 0.8 %
* Record 2 0.8 %
* --- -------
* 242 100.0 %
*
* When there is an access path leading to the final operand (e.g. a record
* component), only the final data type on the access path is counted.
*
*
* 4. Operand Locality:
* -------------------
* number approximate
* percentage
*
* local variable 114 47.1 %
* global variable 22 9.1 %
* parameter 45 18.6 %
* value 23 9.5 %
* reference 22 9.1 %
* function result 6 2.5 %
* constant 55 22.7 %
* --- -------
* 242 100.0 %
*
* The program does not compute anything meaningful, but it is syntactically
* and semantically correct. All variables have a value assigned to them
* before they are used as a source operand.
*
* There has been no explicit effort to account for the effects of a
* cache, or to balance the use of long or short displacements for code or
* data.
*
***************************************************************************
*/
/* Compiler and system dependent definitions: */
/* variables for time measurement: */
#ifdef TIME
#define CLOCK_TYPE "time()"
#undef HZ
#define HZ (1) /* time() returns time in seconds */
extern long time(); /* see library function "time" */
#define Too_Small_Time 2 /* Measurements should last at least 2 seconds */
#define Start_Timer() Begin_Time = time ( (long *) 0)
#define Stop_Timer() End_Time = time ( (long *) 0)
#else
#ifdef MSC_CLOCK /* Use Microsoft C hi-res clock */
#undef HZ
#undef TIMES
#include <time.h>
#define HZ CLK_TCK
#define CLOCK_TYPE "MSC clock()"
extern clock_t clock();
#define Too_Small_Time (2*HZ)
#define Start_Timer() Begin_Time = clock()
#define Stop_Timer() End_Time = clock()
#elif defined(__riscv)
#define HZ 1000000
#define Too_Small_Time 1
#define CLOCK_TYPE "rdcycle()"
#define Start_Timer() Begin_Time = read_csr(mcycle)
#define Stop_Timer() End_Time = read_csr(mcycle)
#else
/* Use times(2) time function unless */
/* explicitly defined otherwise */
#define CLOCK_TYPE "times()"
#include <sys/types.h>
#include <sys/times.h>
#ifndef HZ /* Added by SP 900619 */
#include <sys/param.h> /* If your system doesn't have this, use -DHZ=xxx */
#else
*** You must define HZ!!! ***
#endif /* HZ */
#ifndef PASS2
struct tms time_info;
#endif
/*extern int times ();*/
/* see library function "times" */
#define Too_Small_Time (2*HZ)
/* Measurements should last at least about 2 seconds */
#define Start_Timer() times(&time_info); Begin_Time=(long)time_info.tms_utime
#define Stop_Timer() times(&time_info); End_Time = (long)time_info.tms_utime
#endif /* MSC_CLOCK */
#endif /* TIME */
#define Mic_secs_Per_Second 1000000
#define NUMBER_OF_RUNS 500 /* Default number of runs */
#ifdef NOSTRUCTASSIGN
#define structassign(d, s) memcpy(&(d), &(s), sizeof(d))
#else
#define structassign(d, s) d = s
#endif
#ifdef NOENUM
#define Ident_1 0
#define Ident_2 1
#define Ident_3 2
#define Ident_4 3
#define Ident_5 4
typedef int Enumeration;
#else
typedef enum {Ident_1, Ident_2, Ident_3, Ident_4, Ident_5}
Enumeration;
#endif
/* for boolean and enumeration types in Ada, Pascal */
/* General definitions: */
#include <stdio.h>
#include <string.h>
/* for strcpy, strcmp */
#define Null 0
/* Value of a Null pointer */
#define true 1
#define false 0
typedef int One_Thirty;
typedef int One_Fifty;
typedef char Capital_Letter;
typedef int Boolean;
typedef char Str_30 [31];
typedef int Arr_1_Dim [50];
typedef int Arr_2_Dim [50] [50];
typedef struct record
{
struct record *Ptr_Comp;
Enumeration Discr;
union {
struct {
Enumeration Enum_Comp;
int Int_Comp;
char Str_Comp [31];
} var_1;
struct {
Enumeration E_Comp_2;
char Str_2_Comp [31];
} var_2;
struct {
char Ch_1_Comp;
char Ch_2_Comp;
} var_3;
} variant;
} Rec_Type, *Rec_Pointer;
#endif

View file

@ -0,0 +1,332 @@
// See LICENSE for license details.
//**************************************************************************
// Dhrystone bencmark
//--------------------------------------------------------------------------
//
// This is the classic Dhrystone synthetic integer benchmark.
//
#pragma GCC optimize ("no-inline")
#include "dhrystone.h"
void debug_printf(const char* str, ...);
#include "util.h"
#include <alloca.h>
/* Global Variables: */
Rec_Pointer Ptr_Glob,
Next_Ptr_Glob;
int Int_Glob;
Boolean Bool_Glob;
char Ch_1_Glob,
Ch_2_Glob;
int Arr_1_Glob [50];
int Arr_2_Glob [50] [50];
Enumeration Func_1 ();
/* forward declaration necessary since Enumeration may not simply be int */
#ifndef REG
Boolean Reg = false;
#define REG
/* REG becomes defined as empty */
/* i.e. no register variables */
#else
Boolean Reg = true;
#undef REG
#define REG register
#endif
Boolean Done;
long Begin_Time,
End_Time,
User_Time;
long Microseconds,
Dhrystones_Per_Second;
/* end of variables for time measurement */
int main (int argc, char** argv)
/*****/
/* main program, corresponds to procedures */
/* Main and Proc_0 in the Ada version */
{
One_Fifty Int_1_Loc;
REG One_Fifty Int_2_Loc;
One_Fifty Int_3_Loc;
REG char Ch_Index;
Enumeration Enum_Loc;
Str_30 Str_1_Loc;
Str_30 Str_2_Loc;
REG int Run_Index;
REG int Number_Of_Runs;
/* Arguments */
Number_Of_Runs = NUMBER_OF_RUNS;
/* Initializations */
Next_Ptr_Glob = (Rec_Pointer) alloca (sizeof (Rec_Type));
Ptr_Glob = (Rec_Pointer) alloca (sizeof (Rec_Type));
Ptr_Glob->Ptr_Comp = Next_Ptr_Glob;
Ptr_Glob->Discr = Ident_1;
Ptr_Glob->variant.var_1.Enum_Comp = Ident_3;
Ptr_Glob->variant.var_1.Int_Comp = 40;
strcpy (Ptr_Glob->variant.var_1.Str_Comp,
"DHRYSTONE PROGRAM, SOME STRING");
strcpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING");
Arr_2_Glob [8][7] = 10;
/* Was missing in published program. Without this statement, */
/* Arr_2_Glob [8][7] would have an undefined value. */
/* Warning: With 16-Bit processors and Number_Of_Runs > 32000, */
/* overflow may occur for this array element. */
debug_printf("\n");
debug_printf("Dhrystone Benchmark, Version %s\n", Version);
if (Reg)
{
debug_printf("Program compiled with 'register' attribute\n");
}
else
{
debug_printf("Program compiled without 'register' attribute\n");
}
debug_printf("Using %s, HZ=%d\n", CLOCK_TYPE, HZ);
debug_printf("\n");
Done = false;
while (!Done) {
debug_printf("Trying %d runs through Dhrystone:\n", Number_Of_Runs);
/***************/
/* Start timer */
/***************/
setStats(1);
Start_Timer();
for (Run_Index = 1; Run_Index <= Number_Of_Runs; ++Run_Index)
{
Proc_5();
Proc_4();
/* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */
Int_1_Loc = 2;
Int_2_Loc = 3;
strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING");
Enum_Loc = Ident_2;
Bool_Glob = ! Func_2 (Str_1_Loc, Str_2_Loc);
/* Bool_Glob == 1 */
while (Int_1_Loc < Int_2_Loc) /* loop body executed once */
{
Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc;
/* Int_3_Loc == 7 */
Proc_7 (Int_1_Loc, Int_2_Loc, &Int_3_Loc);
/* Int_3_Loc == 7 */
Int_1_Loc += 1;
} /* while */
/* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
Proc_8 (Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc);
/* Int_Glob == 5 */
Proc_1 (Ptr_Glob);
for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index)
/* loop body executed twice */
{
if (Enum_Loc == Func_1 (Ch_Index, 'C'))
/* then, not executed */
{
Proc_6 (Ident_1, &Enum_Loc);
strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING");
Int_2_Loc = Run_Index;
Int_Glob = Run_Index;
}
}
/* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
Int_2_Loc = Int_2_Loc * Int_1_Loc;
Int_1_Loc = Int_2_Loc / Int_3_Loc;
Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc;
/* Int_1_Loc == 1, Int_2_Loc == 13, Int_3_Loc == 7 */
Proc_2 (&Int_1_Loc);
/* Int_1_Loc == 5 */
} /* loop "for Run_Index" */
/**************/
/* Stop timer */
/**************/
Stop_Timer();
setStats(0);
User_Time = End_Time - Begin_Time;
if (User_Time < Too_Small_Time)
{
printf("Measured time too small to obtain meaningful results\n");
Number_Of_Runs = Number_Of_Runs * 10;
printf("\n");
} else Done = true;
}
debug_printf("Final values of the variables used in the benchmark:\n");
debug_printf("\n");
debug_printf("Int_Glob: %d\n", Int_Glob);
debug_printf(" should be: %d\n", 5);
debug_printf("Bool_Glob: %d\n", Bool_Glob);
debug_printf(" should be: %d\n", 1);
debug_printf("Ch_1_Glob: %c\n", Ch_1_Glob);
debug_printf(" should be: %c\n", 'A');
debug_printf("Ch_2_Glob: %c\n", Ch_2_Glob);
debug_printf(" should be: %c\n", 'B');
debug_printf("Arr_1_Glob[8]: %d\n", Arr_1_Glob[8]);
debug_printf(" should be: %d\n", 7);
debug_printf("Arr_2_Glob[8][7]: %d\n", Arr_2_Glob[8][7]);
debug_printf(" should be: Number_Of_Runs + 10\n");
debug_printf("Ptr_Glob->\n");
debug_printf(" Ptr_Comp: %d\n", (long) Ptr_Glob->Ptr_Comp);
debug_printf(" should be: (implementation-dependent)\n");
debug_printf(" Discr: %d\n", Ptr_Glob->Discr);
debug_printf(" should be: %d\n", 0);
debug_printf(" Enum_Comp: %d\n", Ptr_Glob->variant.var_1.Enum_Comp);
debug_printf(" should be: %d\n", 2);
debug_printf(" Int_Comp: %d\n", Ptr_Glob->variant.var_1.Int_Comp);
debug_printf(" should be: %d\n", 17);
debug_printf(" Str_Comp: %s\n", Ptr_Glob->variant.var_1.Str_Comp);
debug_printf(" should be: DHRYSTONE PROGRAM, SOME STRING\n");
debug_printf("Next_Ptr_Glob->\n");
debug_printf(" Ptr_Comp: %d\n", (long) Next_Ptr_Glob->Ptr_Comp);
debug_printf(" should be: (implementation-dependent), same as above\n");
debug_printf(" Discr: %d\n", Next_Ptr_Glob->Discr);
debug_printf(" should be: %d\n", 0);
debug_printf(" Enum_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Enum_Comp);
debug_printf(" should be: %d\n", 1);
debug_printf(" Int_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Int_Comp);
debug_printf(" should be: %d\n", 18);
debug_printf(" Str_Comp: %s\n",
Next_Ptr_Glob->variant.var_1.Str_Comp);
debug_printf(" should be: DHRYSTONE PROGRAM, SOME STRING\n");
debug_printf("Int_1_Loc: %d\n", Int_1_Loc);
debug_printf(" should be: %d\n", 5);
debug_printf("Int_2_Loc: %d\n", Int_2_Loc);
debug_printf(" should be: %d\n", 13);
debug_printf("Int_3_Loc: %d\n", Int_3_Loc);
debug_printf(" should be: %d\n", 7);
debug_printf("Enum_Loc: %d\n", Enum_Loc);
debug_printf(" should be: %d\n", 1);
debug_printf("Str_1_Loc: %s\n", Str_1_Loc);
debug_printf(" should be: DHRYSTONE PROGRAM, 1'ST STRING\n");
debug_printf("Str_2_Loc: %s\n", Str_2_Loc);
debug_printf(" should be: DHRYSTONE PROGRAM, 2'ND STRING\n");
debug_printf("\n");
Microseconds = ((User_Time / Number_Of_Runs) * Mic_secs_Per_Second) / HZ;
Dhrystones_Per_Second = (HZ * Number_Of_Runs) / User_Time;
printf("Microseconds for one run through Dhrystone: %ld\n", Microseconds);
printf("Dhrystones per Second: %ld\n", Dhrystones_Per_Second);
return 0;
}
Proc_1 (Ptr_Val_Par)
/******************/
REG Rec_Pointer Ptr_Val_Par;
/* executed once */
{
REG Rec_Pointer Next_Record = Ptr_Val_Par->Ptr_Comp;
/* == Ptr_Glob_Next */
/* Local variable, initialized with Ptr_Val_Par->Ptr_Comp, */
/* corresponds to "rename" in Ada, "with" in Pascal */
structassign (*Ptr_Val_Par->Ptr_Comp, *Ptr_Glob);
Ptr_Val_Par->variant.var_1.Int_Comp = 5;
Next_Record->variant.var_1.Int_Comp
= Ptr_Val_Par->variant.var_1.Int_Comp;
Next_Record->Ptr_Comp = Ptr_Val_Par->Ptr_Comp;
Proc_3 (&Next_Record->Ptr_Comp);
/* Ptr_Val_Par->Ptr_Comp->Ptr_Comp
== Ptr_Glob->Ptr_Comp */
if (Next_Record->Discr == Ident_1)
/* then, executed */
{
Next_Record->variant.var_1.Int_Comp = 6;
Proc_6 (Ptr_Val_Par->variant.var_1.Enum_Comp,
&Next_Record->variant.var_1.Enum_Comp);
Next_Record->Ptr_Comp = Ptr_Glob->Ptr_Comp;
Proc_7 (Next_Record->variant.var_1.Int_Comp, 10,
&Next_Record->variant.var_1.Int_Comp);
}
else /* not executed */
structassign (*Ptr_Val_Par, *Ptr_Val_Par->Ptr_Comp);
} /* Proc_1 */
Proc_2 (Int_Par_Ref)
/******************/
/* executed once */
/* *Int_Par_Ref == 1, becomes 4 */
One_Fifty *Int_Par_Ref;
{
One_Fifty Int_Loc;
Enumeration Enum_Loc;
Int_Loc = *Int_Par_Ref + 10;
do /* executed once */
if (Ch_1_Glob == 'A')
/* then, executed */
{
Int_Loc -= 1;
*Int_Par_Ref = Int_Loc - Int_Glob;
Enum_Loc = Ident_1;
} /* if */
while (Enum_Loc != Ident_1); /* true */
} /* Proc_2 */
Proc_3 (Ptr_Ref_Par)
/******************/
/* executed once */
/* Ptr_Ref_Par becomes Ptr_Glob */
Rec_Pointer *Ptr_Ref_Par;
{
if (Ptr_Glob != Null)
/* then, executed */
*Ptr_Ref_Par = Ptr_Glob->Ptr_Comp;
Proc_7 (10, Int_Glob, &Ptr_Glob->variant.var_1.Int_Comp);
} /* Proc_3 */
Proc_4 () /* without parameters */
/*******/
/* executed once */
{
Boolean Bool_Loc;
Bool_Loc = Ch_1_Glob == 'A';
Bool_Glob = Bool_Loc | Bool_Glob;
Ch_2_Glob = 'B';
} /* Proc_4 */
Proc_5 () /* without parameters */
/*******/
/* executed once */
{
Ch_1_Glob = 'A';
Bool_Glob = false;
} /* Proc_5 */

View file

@ -0,0 +1,53 @@
// See LICENSE for license details.
#define DATA_SIZE 400
int input_data[DATA_SIZE] =
{
41, 454, 833, 335, 564, 1, 187, 989, 749, 365, 350, 572, 132, 64, 949, 153, 584, 216, 805, 140,
621, 210, 6, 572, 931, 339, 890, 593, 392, 898, 694, 228, 961, 12, 110, 883, 116, 750, 296, 646,
426, 500, 314, 436, 659, 701, 774, 812, 319, 981, 678, 150, 875, 696, 376, 564, 474, 272, 938, 258,
539, 647, 569, 509, 203, 88, 280, 703, 759, 669, 606, 375, 511, 551, 657, 936, 195, 592, 81, 569,
267, 952, 229, 800, 337, 584, 944, 643, 902, 368, 241, 489, 913, 328, 826, 313, 933, 592, 985, 388,
195, 543, 960, 649, 566, 979, 350, 997, 649, 814, 657, 79, 181, 208, 111, 998, 859, 629, 65, 847,
288, 704, 349, 997, 141, 253, 905, 715, 886, 430, 264, 415, 576, 538, 979, 700, 761, 4, 241, 494,
478, 100, 499, 864, 403, 693, 222, 416, 444, 296, 721, 285, 676, 620, 317, 78, 224, 351, 937, 540,
288, 646, 119, 169, 615, 527, 606, 289, 389, 796, 351, 801, 455, 720, 278, 758, 367, 745, 358, 92,
584, 989, 62, 271, 985, 853, 403, 788, 346, 531, 517, 222, 559, 461, 908, 241, 775, 358, 255, 332,
778, 684, 598, 740, 143, 446, 33, 311, 125, 743, 941, 557, 933, 479, 799, 557, 553, 925, 431, 796,
648, 357, 952, 891, 287, 666, 19, 514, 49, 557, 86, 870, 95, 853, 441, 440, 587, 61, 614, 678,
382, 396, 280, 9, 808, 17, 971, 170, 819, 291, 344, 380, 450, 536, 512, 185, 965, 917, 347, 539,
808, 983, 882, 887, 537, 54, 946, 612, 701, 951, 356, 479, 567, 151, 891, 7, 22, 641, 568, 335,
665, 730, 423, 95, 434, 728, 158, 280, 2, 395, 84, 688, 247, 911, 49, 476, 435, 815, 792, 729,
869, 265, 486, 127, 414, 236, 369, 214, 548, 180, 518, 6, 888, 503, 682, 596, 284, 173, 264, 643,
499, 346, 290, 599, 897, 68, 215, 849, 731, 658, 688, 619, 251, 121, 786, 131, 555, 828, 302, 667,
528, 433, 544, 487, 322, 753, 947, 125, 287, 626, 824, 14, 304, 10, 788, 403, 733, 106, 959, 703,
366, 818, 722, 964, 294, 406, 975, 874, 653, 856, 748, 86, 91, 60, 378, 660, 105, 667, 102, 153,
381, 121, 651, 98, 825, 412, 840, 236, 356, 12, 148, 423, 54, 965, 140, 216, 955, 621, 343, 361
};
int verify_data[DATA_SIZE] =
{
0, 454, 454, 564, 335, 187, 187, 749, 749, 365, 365, 350, 132, 132, 153, 584, 216, 584, 216, 621,
210, 210, 210, 572, 572, 890, 593, 593, 593, 694, 694, 694, 228, 110, 110, 116, 750, 296, 646, 426,
500, 426, 436, 436, 659, 701, 774, 774, 812, 678, 678, 678, 696, 696, 564, 474, 474, 474, 272, 539,
539, 569, 569, 509, 203, 203, 280, 703, 703, 669, 606, 511, 511, 551, 657, 657, 592, 195, 569, 267,
569, 267, 800, 337, 584, 584, 643, 902, 643, 368, 368, 489, 489, 826, 328, 826, 592, 933, 592, 388,
388, 543, 649, 649, 649, 566, 979, 649, 814, 657, 657, 181, 181, 181, 208, 859, 859, 629, 629, 288,
704, 349, 704, 349, 253, 253, 715, 886, 715, 430, 415, 415, 538, 576, 700, 761, 700, 241, 241, 478,
478, 478, 499, 499, 693, 403, 416, 416, 416, 444, 296, 676, 620, 620, 317, 224, 224, 351, 540, 540,
540, 288, 169, 169, 527, 606, 527, 389, 389, 389, 796, 455, 720, 455, 720, 367, 745, 367, 358, 358,
584, 584, 271, 271, 853, 853, 788, 403, 531, 517, 517, 517, 461, 559, 461, 775, 358, 358, 332, 332,
684, 684, 684, 598, 446, 143, 311, 125, 311, 743, 743, 933, 557, 799, 557, 557, 557, 553, 796, 648,
648, 648, 891, 891, 666, 287, 514, 49, 514, 86, 557, 95, 853, 441, 441, 441, 440, 587, 614, 614,
396, 382, 280, 280, 17, 808, 170, 819, 291, 344, 344, 380, 450, 512, 512, 512, 917, 917, 539, 539,
808, 882, 887, 882, 537, 537, 612, 701, 701, 701, 479, 479, 479, 567, 151, 22, 22, 568, 568, 568,
665, 665, 423, 423, 434, 434, 280, 158, 280, 84, 395, 247, 688, 247, 476, 435, 476, 792, 792, 792,
729, 486, 265, 414, 236, 369, 236, 369, 214, 518, 180, 518, 503, 682, 596, 596, 284, 264, 264, 499,
499, 346, 346, 599, 599, 215, 215, 731, 731, 688, 658, 619, 251, 251, 131, 555, 555, 555, 667, 528,
528, 528, 487, 487, 487, 753, 753, 287, 287, 626, 626, 304, 14, 304, 403, 733, 403, 733, 703, 703,
703, 722, 818, 722, 406, 406, 874, 874, 856, 748, 748, 91, 86, 91, 378, 378, 660, 105, 153, 153,
153, 381, 121, 651, 412, 825, 412, 356, 236, 148, 148, 148, 423, 140, 216, 216, 621, 621, 361, 0
};

View file

@ -0,0 +1,42 @@
// See LICENSE for license details.
//**************************************************************************
// Median filter (c version)
//--------------------------------------------------------------------------
void median( int n, int input[], int results[] )
{
int A, B, C, i;
// Zero the ends
results[0] = 0;
results[n-1] = 0;
// Do the filter
for ( i = 1; i < (n-1); i++ ) {
A = input[i-1];
B = input[i];
C = input[i+1];
if ( A < B ) {
if ( B < C )
results[i] = B;
else if ( C < A )
results[i] = A;
else
results[i] = C;
}
else {
if ( A < C )
results[i] = A;
else if ( C < B )
results[i] = B;
else
results[i] = C;
}
}
}

View file

@ -0,0 +1,11 @@
// See LICENSE for license details.
//**************************************************************************
// Median filters
//--------------------------------------------------------------------------
// Simple C version
void median( int n, int input[], int results[] );
// Simple assembly version
void median_asm( int n, int input[], int results[] );

View file

@ -0,0 +1,140 @@
#!/usr/bin/perl -w
#==========================================================================
# median_gendata.pl
#
# Author : Christopher Batten (cbatten@mit.edu)
# Date : May 9, 2005
#
(our $usageMsg = <<'ENDMSG') =~ s/^\#//gm;
#
# Simple script which creates an input data set and the reference data
# for the median benchmark.
#
ENDMSG
use strict "vars";
use warnings;
no warnings("once");
use Getopt::Long;
#--------------------------------------------------------------------------
# Command line processing
#--------------------------------------------------------------------------
our %opts;
sub usage()
{
print "\n";
print " Usage: median_gendata.pl [options] \n";
print "\n";
print " Options:\n";
print " --help print this message\n";
print " --size size of input data [750]\n";
print " --seed random seed [1]\n";
print "$usageMsg";
exit();
}
sub processCommandLine()
{
$opts{"help"} = 0;
$opts{"size"} = 750;
$opts{"seed"} = 1;
Getopt::Long::GetOptions( \%opts, 'help|?', 'size:i', 'seed:i' ) or usage();
$opts{"help"} and usage();
}
#--------------------------------------------------------------------------
# Helper Functions
#--------------------------------------------------------------------------
sub printArray
{
my $arrayName = $_[0];
my $arrayRef = $_[1];
my $numCols = 20;
my $arrayLen = scalar(@{$arrayRef});
print "int ".$arrayName."[DATA_SIZE] = \n";
print "{\n";
if ( $arrayLen <= $numCols ) {
print " ";
for ( my $i = 0; $i < $arrayLen; $i++ ) {
print sprintf("%3d",$arrayRef->[$i]);
if ( $i != $arrayLen-1 ) {
print ", ";
}
}
print "\n";
}
else {
my $numRows = int($arrayLen/$numCols);
for ( my $j = 0; $j < $numRows; $j++ ) {
print " ";
for ( my $i = 0; $i < $numCols; $i++ ) {
my $index = $j*$numCols + $i;
print sprintf("%3d",$arrayRef->[$index]);
if ( $index != $arrayLen-1 ) {
print ", ";
}
}
print "\n";
}
if ( $arrayLen > ($numRows*$numCols) ) {
print " ";
for ( my $i = 0; $i < ($arrayLen-($numRows*$numCols)); $i++ ) {
my $index = $numCols*$numRows + $i;
print sprintf("%3d",$arrayRef->[$index]);
if ( $index != $arrayLen-1 ) {
print ", ";
}
}
print "\n";
}
}
print "};\n\n";
}
#--------------------------------------------------------------------------
# Main
#--------------------------------------------------------------------------
sub main()
{
processCommandLine();
srand($opts{"seed"});
my @values;
for ( my $i = 0; $i < $opts{"size"}; $i++ ) {
push( @values, int(rand(999)) );
}
my @median;
$median[0] = 0;
$median[$opts{"size"}-1] = 0;
for ( my $i = 1; $i < $opts{"size"}-1; $i++ ) {
my @tempList = ( $values[$i-1], $values[$i], $values[$i+1] );
my @sorted = sort { $a <=> $b } @tempList;
$median[$i] = $sorted[1];
}
print "\n\#define DATA_SIZE ".$opts{"size"}." \n\n";
printArray( "input_data", \@values );
printArray( "verify_data", \@median );
}
main();

View file

@ -0,0 +1,40 @@
// See LICENSE for license details.
//**************************************************************************
// Median filter bencmark
//--------------------------------------------------------------------------
//
// This benchmark performs a 1D three element median filter. The
// input data (and reference data) should be generated using the
// median_gendata.pl perl script and dumped to a file named
// dataset1.h.
#include "util.h"
#include "median.h"
//--------------------------------------------------------------------------
// Input/Reference Data
#include "dataset1.h"
//--------------------------------------------------------------------------
// Main
int main( int argc, char* argv[] )
{
int results_data[DATA_SIZE];
#if PREALLOCATE
// If needed we preallocate everything in the caches
median( DATA_SIZE, input_data, results_data );
#endif
// Do the filter
setStats(1);
median( DATA_SIZE, input_data, results_data );
setStats(0);
// Check the results
return verify( DATA_SIZE, results_data, verify_data );
}

View file

@ -0,0 +1,36 @@
// See LICENSE for license details.
#ifndef _MM_H
#define _MM_H
#include <string.h>
#include <stdint.h>
#include <math.h>
#ifdef SP
typedef float t;
#define fma fmaf
#else
typedef double t;
#endif
#define inline inline __attribute__((always_inline))
#define alloca_aligned(s, a) ((void*)(((uintptr_t)alloca((s)+(a)-1)+(a)-1)&~((a)-1)))
#include "rb.h"
#ifdef __cplusplus
extern "C" {
#endif
void mm(size_t m, size_t n, size_t p,
t* a, size_t lda, t* b, size_t ldb, t* c, size_t ldc);
#ifdef __cplusplus
}
#endif
//void rb(t* a, t* b, t* c, size_t lda, size_t ldb, size_t ldc);
#endif

View file

@ -0,0 +1,81 @@
import scala.sys.process._
object MMGen {
implicit def i2s(i: Int) = i.toString
def writeFile(name: String, contents: String) = {
val f = new java.io.FileWriter(name)
f.write(contents)
f.close
}
var indent = 0
def spacing = " " * indent
def assign(lhs: String, rhs: String) =
spacing + lhs + " = " + rhs + ";\n"
def init(t: String, n: String, v: String) =
assign(t+" "+n, v)
def open_block(s: String = "") = {
val result = (if (s != "") spacing + s else "") + spacing + "{\n"
indent = indent + 1
result
}
def close_block = {
indent = indent - 1
spacing + "}\n"
}
def ar(m: String, i: String) = m+"["+i+"]"
def r(a: String, b: String*) = (a :: b.toList).reduceLeft(_+"_"+_)
def rb(m: Int, n: Int, p: Int) = {
var s = open_block("static inline void kloop(size_t p, t* a0, size_t lda, t* b0, size_t ldb, t* c, size_t ldc)\n")
for (i <- 0 until m)
s += init("t*", r("c", i), "&"+ar("c", "ldc*"+i))
for (i <- 0 until m; j <- 0 until n)
s += init("t", r("c", i, j), ar(r("c", i), j))
def doit(m: Int, n: Int, p: Int) = {
for (i <- 0 until m)
s += init("t*", r("a", i), "&"+ar("a", "lda*"+i))
for (k <- 0 until p)
s += init("t*", r("b", k), "&"+ar("b", "ldb*"+k))
for (k <- 0 until p; i <- 0 until m; j <- 0 until n)
s += assign(r("c", i, j), "fma(" + ar(r("a", i), k) + ", " + ar(r("b", k), j) + ", " + r("c", i, j) + ")")
}
s += open_block("for (t *a = a0, *b = b0; a < a0 + p/RBK*RBK; a += RBK, b += RBK*ldb)\n")
doit(m, n, p)
s += close_block
s += open_block("for (t *a = a0 + p/RBK*RBK, *b = b0 + p/RBK*RBK*ldb; a < a0 + p; a++, b += ldb)\n")
doit(m, n, 1)
s += close_block
for (i <- 0 until m; j <- 0 until n)
s += assign(ar(r("c", i), j), r("c", i, j))
s += close_block
s
}
def gcd(a: Int, b: Int): Int = if (b == 0) a else gcd(b, a%b)
def lcm(a: Int, b: Int): Int = a*b/gcd(a, b)
def lcm(a: Seq[Int]): Int = {
if (a.tail.isEmpty) a.head
else lcm(a.head, lcm(a.tail))
}
def test1(m: Int, n: Int, p: Int, m1: Int, n1: Int, p1: Int) = {
val decl = "static const int RBM = "+m+", RBN = "+n+", RBK = "+p+";\n" +
"static const int CBM = "+m1+", CBN = "+n1+", CBK = "+p1+";\n"
writeFile("rb.h", decl + rb(m, n, p))
//"make"!!
"make run"!
("cp a.out " + Seq("b", m, n, p, m1, n1, p1, "run").reduce(_+"."+_))!
}
def main(args: Array[String]): Unit = {
test1(4, 5, 6, 24, 25, 24)
//for (i <- 4 to 6; j <- 4 to 6; k <- 4 to 6)
// test1(i, j, k, if (i == 5) 35 else 36, if (j == 5) 35 else 36, if (k == 5) 35 else 36)
}
}

152
vendor/riscv-tests/benchmarks/mm/mm.c vendored Normal file
View file

@ -0,0 +1,152 @@
// See LICENSE for license details.
#include "common.h"
#include <assert.h>
#include <math.h>
#include <stdint.h>
#include <alloca.h>
#define MIN(a, b) ((a) < (b) ? (a) : (b))
static void mm_naive(size_t m, size_t n, size_t p,
t* a, size_t lda, t* b, size_t ldb, t* c, size_t ldc)
{
for (size_t i = 0; i < m; i++)
{
for (size_t j = 0; j < n; j++)
{
t s0 = c[i*ldc+j], s1 = 0, s2 = 0, s3 = 0;
for (size_t k = 0; k < p/4*4; k+=4)
{
s0 = fma(a[i*lda+k+0], b[(k+0)*ldb+j], s0);
s1 = fma(a[i*lda+k+1], b[(k+1)*ldb+j], s1);
s2 = fma(a[i*lda+k+2], b[(k+2)*ldb+j], s2);
s3 = fma(a[i*lda+k+3], b[(k+3)*ldb+j], s3);
}
for (size_t k = p/4*4; k < p; k++)
s0 = fma(a[i*lda+k], b[k*ldb+j], s0);
c[i*ldc+j] = (s0 + s1) + (s2 + s3);
}
}
}
static inline void mm_rb(size_t m, size_t n, size_t p,
t* a, size_t lda, t* b, size_t ldb, t* c, size_t ldc)
{
size_t mb = m/RBM*RBM, nb = n/RBN*RBN;
for (size_t i = 0; i < mb; i += RBM)
{
for (size_t j = 0; j < nb; j += RBN)
kloop(p, a+i*lda, lda, b+j, ldb, c+i*ldc+j, ldc);
mm_naive(RBM, n - nb, p, a+i*lda, lda, b+nb, ldb, c+i*ldc+nb, ldc);
}
mm_naive(m - mb, n, p, a+mb*lda, lda, b, ldb, c+mb*ldc, ldc);
}
static inline void repack(t* a, size_t lda, const t* a0, size_t lda0, size_t m, size_t p)
{
for (size_t i = 0; i < m; i++)
{
for (size_t j = 0; j < p/8*8; j+=8)
{
t t0 = a0[i*lda0+j+0];
t t1 = a0[i*lda0+j+1];
t t2 = a0[i*lda0+j+2];
t t3 = a0[i*lda0+j+3];
t t4 = a0[i*lda0+j+4];
t t5 = a0[i*lda0+j+5];
t t6 = a0[i*lda0+j+6];
t t7 = a0[i*lda0+j+7];
a[i*lda+j+0] = t0;
a[i*lda+j+1] = t1;
a[i*lda+j+2] = t2;
a[i*lda+j+3] = t3;
a[i*lda+j+4] = t4;
a[i*lda+j+5] = t5;
a[i*lda+j+6] = t6;
a[i*lda+j+7] = t7;
}
for (size_t j = p/8*8; j < p; j++)
a[i*lda+j] = a0[i*lda0+j];
}
}
static void mm_cb(size_t m, size_t n, size_t p,
t* a, size_t lda, t* b, size_t ldb, t* c, size_t ldc)
{
size_t nmb = m/CBM, nnb = n/CBN, npb = p/CBK;
size_t mb = nmb*CBM, nb = nnb*CBN, pb = npb*CBK;
//t a1[mb*pb], b1[pb*nb], c1[mb*nb];
t* a1 = (t*)alloca_aligned(sizeof(t)*mb*pb, 8192);
t* b1 = (t*)alloca_aligned(sizeof(t)*pb*nb, 8192);
t* c1 = (t*)alloca_aligned(sizeof(t)*mb*nb, 8192);
for (size_t i = 0; i < mb; i += CBM)
for (size_t j = 0; j < pb; j += CBK)
repack(a1 + (npb*(i/CBM) + j/CBK)*(CBM*CBK), CBK, a + i*lda + j, lda, CBM, CBK);
for (size_t i = 0; i < pb; i += CBK)
for (size_t j = 0; j < nb; j += CBN)
repack(b1 + (nnb*(i/CBK) + j/CBN)*(CBK*CBN), CBN, b + i*ldb + j, ldb, CBK, CBN);
for (size_t i = 0; i < mb; i += CBM)
for (size_t j = 0; j < nb; j += CBN)
repack(c1 + (nnb*(i/CBM) + j/CBN)*(CBM*CBN), CBN, c + i*ldc + j, ldc, CBM, CBN);
for (size_t i = 0; i < mb; i += CBM)
{
for (size_t j = 0; j < nb; j += CBN)
{
for (size_t k = 0; k < pb; k += CBK)
{
mm_rb(CBM, CBN, CBK,
a1 + (npb*(i/CBM) + k/CBK)*(CBM*CBK), CBK,
b1 + (nnb*(k/CBK) + j/CBN)*(CBK*CBN), CBN,
c1 + (nnb*(i/CBM) + j/CBN)*(CBM*CBN), CBN);
}
if (pb < p)
{
mm_rb(CBM, CBN, p - pb,
a + i*lda + pb, lda,
b + pb*ldb + j, ldb,
c1 + (nnb*(i/CBM) + j/CBN)*(CBM*CBN), CBN);
}
}
if (nb < n)
{
for (size_t k = 0; k < p; k += CBK)
{
mm_rb(CBM, n - nb, MIN(p - k, CBK),
a + i*lda + k, lda,
b + k*ldb + nb, ldb,
c + i*ldc + nb, ldc);
}
}
}
if (mb < m)
{
for (size_t j = 0; j < n; j += CBN)
{
for (size_t k = 0; k < p; k += CBK)
{
mm_rb(m - mb, MIN(n - j, CBN), MIN(p - k, CBK),
a + mb*lda + k, lda,
b + k*ldb + j, ldb,
c + mb*ldc + j, ldc);
}
}
}
for (size_t i = 0; i < mb; i += CBM)
for (size_t j = 0; j < nb; j += CBN)
repack(c + i*ldc + j, ldc, c1 + (nnb*(i/CBM) + j/CBN)*(CBM*CBN), CBN, CBM, CBN);
}
void mm(size_t m, size_t n, size_t p,
t* a, size_t lda, t* b, size_t ldb, t* c, size_t ldc)
{
if (__builtin_expect(m <= 2*CBM && n <= 2*CBN && p <= 2*CBK, 1))
mm_rb(m, n, p, a, lda, b, ldb, c, ldc);
else
mm_cb(m, n, p, a, lda, b, ldb, c, ldc);
}

View file

@ -0,0 +1,72 @@
// See LICENSE for license details.
#include "common.h"
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include "util.h"
#pragma GCC optimize ("unroll-loops")
void thread_entry(int cid, int nc)
{
const int R = 8;
int m, n, p;
uint64_t s = 0xdeadbeefU;
m = CBM;
n = CBN;
p = CBK;
t a[m*p];
t b[p*n];
t c[m*n];
for (size_t i = 0; i < m; i++)
for (size_t j = 0; j < p; j++)
a[i*p+j] = (t)(s = lfsr(s));
for (size_t i = 0; i < p; i++)
for (size_t j = 0; j < n; j++)
b[i*n+j] = (t)(s = lfsr(s));
memset(c, 0, m*n*sizeof(c[0]));
size_t instret, cycles;
for (int i = 0; i < R; i++)
{
instret = -read_csr(minstret);
cycles = -read_csr(mcycle);
mm(m, n, p, a, p, b, n, c, n);
instret += read_csr(minstret);
cycles += read_csr(mcycle);
}
asm volatile("fence");
printf("C%d: reg block %dx%dx%d, cache block %dx%dx%d\n",
cid, RBM, RBN, RBK, CBM, CBN, CBK);
printf("C%d: %d instructions\n", cid, (int)(instret));
printf("C%d: %d cycles\n", cid, (int)(cycles));
printf("C%d: %d flops\n", cid, 2*m*n*p);
printf("C%d: %d Mflops @ 1 GHz\n", cid, 2000*m*n*p/(cycles));
#if 1
for (size_t i = 0; i < m; i++)
{
for (size_t j = 0; j < n; j++)
{
t s = 0;
for (size_t k = 0; k < p; k++)
s += a[i*p+k] * b[k*n+j];
s *= R;
if (fabs(c[i*n+j]-s) > fabs(1e-6*s))
{
printf("C%d: c[%lu][%lu] %f != %f\n", cid, i, j, c[i*n+j], s);
exit(1);
}
}
}
#endif
barrier(nc);
exit(0);
}

210
vendor/riscv-tests/benchmarks/mm/rb.h vendored Normal file
View file

@ -0,0 +1,210 @@
static const int RBM = 4, RBN = 5, RBK = 6;
static const int CBM = 24, CBN = 25, CBK = 24;
static inline void kloop(size_t p, t* a0, size_t lda, t* b0, size_t ldb, t* c, size_t ldc)
{
t* c_0 = &c[ldc*0];
t* c_1 = &c[ldc*1];
t* c_2 = &c[ldc*2];
t* c_3 = &c[ldc*3];
t c_0_0 = c_0[0];
t c_0_1 = c_0[1];
t c_0_2 = c_0[2];
t c_0_3 = c_0[3];
t c_0_4 = c_0[4];
t c_1_0 = c_1[0];
t c_1_1 = c_1[1];
t c_1_2 = c_1[2];
t c_1_3 = c_1[3];
t c_1_4 = c_1[4];
t c_2_0 = c_2[0];
t c_2_1 = c_2[1];
t c_2_2 = c_2[2];
t c_2_3 = c_2[3];
t c_2_4 = c_2[4];
t c_3_0 = c_3[0];
t c_3_1 = c_3[1];
t c_3_2 = c_3[2];
t c_3_3 = c_3[3];
t c_3_4 = c_3[4];
for (t *a = a0, *b = b0; a < a0 + p/RBK*RBK; a += RBK, b += RBK*ldb)
{
t* a_0 = &a[lda*0];
t* a_1 = &a[lda*1];
t* a_2 = &a[lda*2];
t* a_3 = &a[lda*3];
t* b_0 = &b[ldb*0];
t* b_1 = &b[ldb*1];
t* b_2 = &b[ldb*2];
t* b_3 = &b[ldb*3];
t* b_4 = &b[ldb*4];
t* b_5 = &b[ldb*5];
c_0_0 = fma(a_0[0], b_0[0], c_0_0);
c_0_1 = fma(a_0[0], b_0[1], c_0_1);
c_0_2 = fma(a_0[0], b_0[2], c_0_2);
c_0_3 = fma(a_0[0], b_0[3], c_0_3);
c_0_4 = fma(a_0[0], b_0[4], c_0_4);
c_1_0 = fma(a_1[0], b_0[0], c_1_0);
c_1_1 = fma(a_1[0], b_0[1], c_1_1);
c_1_2 = fma(a_1[0], b_0[2], c_1_2);
c_1_3 = fma(a_1[0], b_0[3], c_1_3);
c_1_4 = fma(a_1[0], b_0[4], c_1_4);
c_2_0 = fma(a_2[0], b_0[0], c_2_0);
c_2_1 = fma(a_2[0], b_0[1], c_2_1);
c_2_2 = fma(a_2[0], b_0[2], c_2_2);
c_2_3 = fma(a_2[0], b_0[3], c_2_3);
c_2_4 = fma(a_2[0], b_0[4], c_2_4);
c_3_0 = fma(a_3[0], b_0[0], c_3_0);
c_3_1 = fma(a_3[0], b_0[1], c_3_1);
c_3_2 = fma(a_3[0], b_0[2], c_3_2);
c_3_3 = fma(a_3[0], b_0[3], c_3_3);
c_3_4 = fma(a_3[0], b_0[4], c_3_4);
c_0_0 = fma(a_0[1], b_1[0], c_0_0);
c_0_1 = fma(a_0[1], b_1[1], c_0_1);
c_0_2 = fma(a_0[1], b_1[2], c_0_2);
c_0_3 = fma(a_0[1], b_1[3], c_0_3);
c_0_4 = fma(a_0[1], b_1[4], c_0_4);
c_1_0 = fma(a_1[1], b_1[0], c_1_0);
c_1_1 = fma(a_1[1], b_1[1], c_1_1);
c_1_2 = fma(a_1[1], b_1[2], c_1_2);
c_1_3 = fma(a_1[1], b_1[3], c_1_3);
c_1_4 = fma(a_1[1], b_1[4], c_1_4);
c_2_0 = fma(a_2[1], b_1[0], c_2_0);
c_2_1 = fma(a_2[1], b_1[1], c_2_1);
c_2_2 = fma(a_2[1], b_1[2], c_2_2);
c_2_3 = fma(a_2[1], b_1[3], c_2_3);
c_2_4 = fma(a_2[1], b_1[4], c_2_4);
c_3_0 = fma(a_3[1], b_1[0], c_3_0);
c_3_1 = fma(a_3[1], b_1[1], c_3_1);
c_3_2 = fma(a_3[1], b_1[2], c_3_2);
c_3_3 = fma(a_3[1], b_1[3], c_3_3);
c_3_4 = fma(a_3[1], b_1[4], c_3_4);
c_0_0 = fma(a_0[2], b_2[0], c_0_0);
c_0_1 = fma(a_0[2], b_2[1], c_0_1);
c_0_2 = fma(a_0[2], b_2[2], c_0_2);
c_0_3 = fma(a_0[2], b_2[3], c_0_3);
c_0_4 = fma(a_0[2], b_2[4], c_0_4);
c_1_0 = fma(a_1[2], b_2[0], c_1_0);
c_1_1 = fma(a_1[2], b_2[1], c_1_1);
c_1_2 = fma(a_1[2], b_2[2], c_1_2);
c_1_3 = fma(a_1[2], b_2[3], c_1_3);
c_1_4 = fma(a_1[2], b_2[4], c_1_4);
c_2_0 = fma(a_2[2], b_2[0], c_2_0);
c_2_1 = fma(a_2[2], b_2[1], c_2_1);
c_2_2 = fma(a_2[2], b_2[2], c_2_2);
c_2_3 = fma(a_2[2], b_2[3], c_2_3);
c_2_4 = fma(a_2[2], b_2[4], c_2_4);
c_3_0 = fma(a_3[2], b_2[0], c_3_0);
c_3_1 = fma(a_3[2], b_2[1], c_3_1);
c_3_2 = fma(a_3[2], b_2[2], c_3_2);
c_3_3 = fma(a_3[2], b_2[3], c_3_3);
c_3_4 = fma(a_3[2], b_2[4], c_3_4);
c_0_0 = fma(a_0[3], b_3[0], c_0_0);
c_0_1 = fma(a_0[3], b_3[1], c_0_1);
c_0_2 = fma(a_0[3], b_3[2], c_0_2);
c_0_3 = fma(a_0[3], b_3[3], c_0_3);
c_0_4 = fma(a_0[3], b_3[4], c_0_4);
c_1_0 = fma(a_1[3], b_3[0], c_1_0);
c_1_1 = fma(a_1[3], b_3[1], c_1_1);
c_1_2 = fma(a_1[3], b_3[2], c_1_2);
c_1_3 = fma(a_1[3], b_3[3], c_1_3);
c_1_4 = fma(a_1[3], b_3[4], c_1_4);
c_2_0 = fma(a_2[3], b_3[0], c_2_0);
c_2_1 = fma(a_2[3], b_3[1], c_2_1);
c_2_2 = fma(a_2[3], b_3[2], c_2_2);
c_2_3 = fma(a_2[3], b_3[3], c_2_3);
c_2_4 = fma(a_2[3], b_3[4], c_2_4);
c_3_0 = fma(a_3[3], b_3[0], c_3_0);
c_3_1 = fma(a_3[3], b_3[1], c_3_1);
c_3_2 = fma(a_3[3], b_3[2], c_3_2);
c_3_3 = fma(a_3[3], b_3[3], c_3_3);
c_3_4 = fma(a_3[3], b_3[4], c_3_4);
c_0_0 = fma(a_0[4], b_4[0], c_0_0);
c_0_1 = fma(a_0[4], b_4[1], c_0_1);
c_0_2 = fma(a_0[4], b_4[2], c_0_2);
c_0_3 = fma(a_0[4], b_4[3], c_0_3);
c_0_4 = fma(a_0[4], b_4[4], c_0_4);
c_1_0 = fma(a_1[4], b_4[0], c_1_0);
c_1_1 = fma(a_1[4], b_4[1], c_1_1);
c_1_2 = fma(a_1[4], b_4[2], c_1_2);
c_1_3 = fma(a_1[4], b_4[3], c_1_3);
c_1_4 = fma(a_1[4], b_4[4], c_1_4);
c_2_0 = fma(a_2[4], b_4[0], c_2_0);
c_2_1 = fma(a_2[4], b_4[1], c_2_1);
c_2_2 = fma(a_2[4], b_4[2], c_2_2);
c_2_3 = fma(a_2[4], b_4[3], c_2_3);
c_2_4 = fma(a_2[4], b_4[4], c_2_4);
c_3_0 = fma(a_3[4], b_4[0], c_3_0);
c_3_1 = fma(a_3[4], b_4[1], c_3_1);
c_3_2 = fma(a_3[4], b_4[2], c_3_2);
c_3_3 = fma(a_3[4], b_4[3], c_3_3);
c_3_4 = fma(a_3[4], b_4[4], c_3_4);
c_0_0 = fma(a_0[5], b_5[0], c_0_0);
c_0_1 = fma(a_0[5], b_5[1], c_0_1);
c_0_2 = fma(a_0[5], b_5[2], c_0_2);
c_0_3 = fma(a_0[5], b_5[3], c_0_3);
c_0_4 = fma(a_0[5], b_5[4], c_0_4);
c_1_0 = fma(a_1[5], b_5[0], c_1_0);
c_1_1 = fma(a_1[5], b_5[1], c_1_1);
c_1_2 = fma(a_1[5], b_5[2], c_1_2);
c_1_3 = fma(a_1[5], b_5[3], c_1_3);
c_1_4 = fma(a_1[5], b_5[4], c_1_4);
c_2_0 = fma(a_2[5], b_5[0], c_2_0);
c_2_1 = fma(a_2[5], b_5[1], c_2_1);
c_2_2 = fma(a_2[5], b_5[2], c_2_2);
c_2_3 = fma(a_2[5], b_5[3], c_2_3);
c_2_4 = fma(a_2[5], b_5[4], c_2_4);
c_3_0 = fma(a_3[5], b_5[0], c_3_0);
c_3_1 = fma(a_3[5], b_5[1], c_3_1);
c_3_2 = fma(a_3[5], b_5[2], c_3_2);
c_3_3 = fma(a_3[5], b_5[3], c_3_3);
c_3_4 = fma(a_3[5], b_5[4], c_3_4);
}
for (t *a = a0 + p/RBK*RBK, *b = b0 + p/RBK*RBK*ldb; a < a0 + p; a++, b += ldb)
{
t* a_0 = &a[lda*0];
t* a_1 = &a[lda*1];
t* a_2 = &a[lda*2];
t* a_3 = &a[lda*3];
t* b_0 = &b[ldb*0];
c_0_0 = fma(a_0[0], b_0[0], c_0_0);
c_0_1 = fma(a_0[0], b_0[1], c_0_1);
c_0_2 = fma(a_0[0], b_0[2], c_0_2);
c_0_3 = fma(a_0[0], b_0[3], c_0_3);
c_0_4 = fma(a_0[0], b_0[4], c_0_4);
c_1_0 = fma(a_1[0], b_0[0], c_1_0);
c_1_1 = fma(a_1[0], b_0[1], c_1_1);
c_1_2 = fma(a_1[0], b_0[2], c_1_2);
c_1_3 = fma(a_1[0], b_0[3], c_1_3);
c_1_4 = fma(a_1[0], b_0[4], c_1_4);
c_2_0 = fma(a_2[0], b_0[0], c_2_0);
c_2_1 = fma(a_2[0], b_0[1], c_2_1);
c_2_2 = fma(a_2[0], b_0[2], c_2_2);
c_2_3 = fma(a_2[0], b_0[3], c_2_3);
c_2_4 = fma(a_2[0], b_0[4], c_2_4);
c_3_0 = fma(a_3[0], b_0[0], c_3_0);
c_3_1 = fma(a_3[0], b_0[1], c_3_1);
c_3_2 = fma(a_3[0], b_0[2], c_3_2);
c_3_3 = fma(a_3[0], b_0[3], c_3_3);
c_3_4 = fma(a_3[0], b_0[4], c_3_4);
}
c_0[0] = c_0_0;
c_0[1] = c_0_1;
c_0[2] = c_0_2;
c_0[3] = c_0_3;
c_0[4] = c_0_4;
c_1[0] = c_1_0;
c_1[1] = c_1_1;
c_1[2] = c_1_2;
c_1[3] = c_1_3;
c_1[4] = c_1_4;
c_2[0] = c_2_0;
c_2[1] = c_2_1;
c_2[2] = c_2_2;
c_2[3] = c_2_3;
c_2[4] = c_2_4;
c_3[0] = c_3_0;
c_3[1] = c_3_1;
c_3[2] = c_3_2;
c_3[3] = c_3_3;
c_3[4] = c_3_4;
}

View file

@ -0,0 +1,63 @@
// See LICENSE for license details.
#ifndef __DATASET_H
#define __DATASET_H
#define ARRAY_SIZE 256
#define DIM_SIZE 16
typedef int data_t;static data_t input1_data[ARRAY_SIZE] =
{
0, 3, 2, 0, 3, 1, 0, 3, 2, 3, 2, 0, 3, 3, 1, 2, 3, 0, 0, 1,
1, 1, 2, 3, 1, 2, 3, 1, 1, 3, 2, 2, 0, 1, 3, 2, 2, 2, 0, 0,
1, 0, 1, 3, 3, 0, 3, 3, 3, 3, 0, 3, 2, 1, 2, 2, 0, 0, 3, 0,
1, 1, 0, 3, 3, 1, 2, 3, 3, 0, 1, 2, 1, 0, 1, 2, 2, 1, 0, 3,
1, 0, 2, 2, 1, 1, 1, 1, 1, 1, 2, 0, 3, 1, 1, 2, 2, 3, 3, 1,
3, 2, 0, 0, 0, 3, 3, 3, 2, 1, 2, 3, 1, 0, 0, 0, 0, 1, 2, 2,
1, 1, 3, 3, 3, 1, 1, 2, 3, 1, 3, 3, 2, 3, 2, 1, 2, 3, 0, 2,
2, 1, 1, 0, 0, 0, 0, 0, 1, 3, 3, 1, 1, 1, 2, 2, 3, 2, 1, 1,
1, 1, 3, 0, 2, 2, 1, 3, 2, 1, 2, 2, 1, 3, 1, 3, 1, 3, 2, 3,
1, 2, 1, 3, 2, 2, 0, 1, 0, 0, 1, 2, 3, 3, 1, 0, 0, 0, 3, 1,
2, 3, 2, 3, 2, 0, 0, 0, 0, 0, 3, 1, 3, 0, 0, 0, 3, 1, 1, 1,
1, 2, 1, 2, 3, 2, 0, 0, 2, 2, 3, 0, 3, 0, 0, 3, 0, 3, 1, 3,
3, 1, 1, 1, 2, 2, 1, 3, 0, 3, 3, 1, 0, 0, 3, 2
};
static data_t input2_data[ARRAY_SIZE] =
{
1, 1, 0, 3, 1, 2, 0, 0, 0, 0, 0, 2, 1, 2, 3, 0, 0, 3, 3, 2,
2, 1, 2, 3, 3, 0, 2, 2, 1, 1, 2, 2, 0, 2, 2, 1, 2, 3, 2, 2,
3, 3, 2, 2, 1, 1, 1, 1, 2, 1, 2, 2, 3, 3, 3, 0, 0, 3, 2, 3,
2, 3, 1, 2, 1, 1, 2, 2, 0, 1, 0, 3, 2, 1, 1, 1, 2, 0, 1, 2,
2, 0, 2, 1, 3, 3, 2, 3, 2, 0, 3, 1, 3, 3, 2, 0, 1, 0, 1, 1,
2, 2, 1, 1, 2, 2, 1, 2, 3, 3, 1, 3, 2, 2, 2, 3, 3, 1, 0, 2,
1, 0, 0, 0, 1, 1, 2, 0, 3, 2, 3, 3, 0, 2, 3, 1, 0, 0, 2, 1,
2, 0, 2, 1, 1, 2, 3, 1, 3, 2, 1, 0, 0, 0, 0, 0, 2, 2, 0, 2,
1, 2, 0, 3, 2, 2, 0, 0, 3, 2, 1, 1, 3, 0, 2, 0, 0, 1, 0, 2,
3, 3, 1, 3, 3, 0, 0, 2, 2, 0, 0, 0, 1, 0, 0, 1, 3, 0, 2, 1,
3, 2, 2, 1, 3, 2, 0, 1, 2, 2, 3, 2, 1, 1, 1, 1, 3, 0, 1, 3,
2, 2, 3, 1, 1, 2, 0, 2, 1, 1, 2, 3, 1, 0, 1, 0, 1, 1, 0, 0,
2, 0, 3, 0, 3, 0, 3, 2, 2, 3, 3, 2, 1, 0, 2, 2
};
static data_t verify_data[ARRAY_SIZE] =
{
36, 44, 57, 50, 54, 36, 38, 46, 55, 25, 38, 34, 51, 30, 40, 32, 37, 34, 38, 52,
51, 40, 28, 32, 41, 22, 26, 35, 49, 35, 42, 23, 26, 26, 33, 36, 52, 40, 45, 49,
50, 34, 41, 35, 44, 25, 23, 23, 31, 29, 39, 46, 50, 36, 31, 32, 42, 32, 34, 41,
44, 33, 43, 30, 31, 28, 39, 46, 50, 40, 35, 37, 43, 35, 33, 43, 43, 29, 37, 29,
27, 22, 30, 33, 43, 31, 32, 25, 36, 31, 31, 29, 40, 28, 26, 22, 29, 42, 48, 51,
65, 52, 43, 54, 63, 34, 42, 44, 56, 33, 38, 32, 26, 22, 23, 38, 49, 32, 26, 30,
43, 22, 24, 27, 45, 24, 26, 17, 35, 35, 47, 51, 59, 59, 43, 42, 43, 28, 37, 43,
56, 48, 36, 32, 28, 19, 28, 34, 46, 34, 28, 34, 45, 20, 29, 28, 50, 32, 26, 21,
37, 38, 51, 50, 55, 45, 38, 49, 56, 28, 38, 40, 50, 29, 44, 26, 32, 35, 50, 43,
53, 44, 41, 41, 34, 24, 35, 34, 39, 33, 34, 29, 21, 33, 31, 45, 48, 42, 27, 29,
40, 17, 21, 32, 45, 30, 29, 26, 26, 27, 38, 33, 29, 31, 32, 31, 35, 25, 29, 29,
34, 15, 25, 23, 34, 28, 44, 45, 41, 41, 37, 45, 45, 17, 34, 44, 46, 30, 43, 29,
31, 36, 37, 50, 54, 44, 28, 40, 38, 22, 27, 28, 45, 32, 36, 22
};
#endif //__DATASET_H

View file

@ -0,0 +1,23 @@
// See LICENSE for license details.
#include "dataset.h"
#include "util.h"
#include <stddef.h>
#pragma GCC optimize ("unroll-loops")
void matmul(const size_t coreid, const size_t ncores, const size_t lda, const data_t A[], const data_t B[], data_t C[])
{
size_t i, j, k;
size_t block = lda / ncores;
size_t start = block * coreid;
for (i = 0; i < lda; i++) {
for (j = start; j < (start+block); j++) {
data_t sum = 0;
for (k = 0; k < lda; k++)
sum += A[j*lda + k] * B[k*lda + i];
C[i + j*lda] = sum;
}
}
}

View file

@ -0,0 +1,205 @@
#!/usr/bin/perl -w
#==========================================================================
# matmul_gendata.pl
#
# Author : Christopher Batten (cbatten@mit.edu)
# Date : April 29, 2005
#
(our $usageMsg = <<'ENDMSG') =~ s/^\#//gm;
#
# Simple script which creates an input data set and the reference data
# for the matmul benchmark.
#
ENDMSG
use strict "vars";
use warnings;
no warnings("once");
use Getopt::Long;
#--------------------------------------------------------------------------
# Command line processing
#--------------------------------------------------------------------------
our %opts;
sub usage()
{
print "\n";
print " Usage: matmul_gendata.pl [options] \n";
print "\n";
print " Options:\n";
print " --help print this message\n";
print " --size size of input data [1000]\n";
print " --seed random seed [1]\n";
print "$usageMsg";
exit();
}
sub processCommandLine()
{
$opts{"help"} = 0;
$opts{"size"} = 1000;
$opts{"seed"} = 1;
Getopt::Long::GetOptions( \%opts, 'help|?', 'size:i', 'seed:i' ) or usage();
$opts{"help"} and usage();
}
#--------------------------------------------------------------------------
# Helper Functions
#--------------------------------------------------------------------------
sub printArray
{
my $arrayName = $_[0];
my $arrayRef = $_[1];
my $numCols = 20;
my $arrayLen = scalar(@{$arrayRef});
print "static data_t ".$arrayName."[ARRAY_SIZE] = \n";
print "{\n";
if ( $arrayLen <= $numCols ) {
print " ";
for ( my $i = 0; $i < $arrayLen; $i++ ) {
print sprintf("%3d",$arrayRef->[$i]);
if ( $i != $arrayLen-1 ) {
print ", ";
}
}
print "\n";
}
else {
my $numRows = int($arrayLen/$numCols);
for ( my $j = 0; $j < $numRows; $j++ ) {
print " ";
for ( my $i = 0; $i < $numCols; $i++ ) {
my $index = $j*$numCols + $i;
print sprintf("%3d",$arrayRef->[$index]);
if ( $index != $arrayLen-1 ) {
print ", ";
}
}
print "\n";
}
if ( $arrayLen > ($numRows*$numCols) ) {
print " ";
for ( my $i = 0; $i < ($arrayLen-($numRows*$numCols)); $i++ ) {
my $index = $numCols*$numRows + $i;
print sprintf("%3d",$arrayRef->[$index]);
if ( $index != $arrayLen-1 ) {
print ", ";
}
}
print "\n";
}
}
print "};\n\n";
}
#--------------------------------------------------------------------------
# Matmul
#--------------------------------------------------------------------------
# http://answers.oreilly.com/topic/418-how-to-multiply-matrices-in-perl/
sub mmult {
my ($m1,$m2) = @_;
my ($m1rows,$m1cols) = matdim($m1);
my ($m2rows,$m2cols) = matdim($m2);
my $result = [ ];
my ($i, $j, $k);
for $i (range($m1rows)) {
for $j (range($m2cols)) {
for $k (range($m1cols)) {
$result->[$i][$j] += $m1->[$i][$k] * $m2->[$k][$j];
}
}
}
return $result;
}
sub range { 0 .. ($_[0] - 1) }
sub veclen {
my $ary_ref = $_[0];
my $type = ref $ary_ref;
if ($type ne "ARRAY") { die "$type is bad array ref for $ary_ref" }
return scalar(@$ary_ref);
}
sub matdim {
my $matrix = $_[0];
my $rows = veclen($matrix);
my $cols = veclen($matrix->[0]);
return ($rows, $cols);
}
#--------------------------------------------------------------------------
# Main
#--------------------------------------------------------------------------
sub main()
{
processCommandLine();
srand($opts{"seed"});
# create random input arrays
my $mat_values1;
my $mat_values2;
for ( my $i = 0; $i < $opts{"size"}; $i++ ) {
for ( my $j = 0; $j < $opts{"size"}; $j++ ) {
$mat_values1->[$i][$j] = int(rand(4));
$mat_values2->[$i][$j] = int(rand(4));
}
}
# perform matmul
my $mat_results = mmult( $mat_values1, $mat_values2 );
# translate 2d arrays to 1d-somethings (I don't know how to code in perl - Chris)
my @values1;
my @values2;
my @results;
for ( my $i = 0; $i < $opts{"size"}; $i++ ) {
for ( my $j = 0; $j < $opts{"size"}; $j++ ) {
my $value1 = $mat_values1->[$i][$j];
my $value2 = $mat_values2->[$i][$j];
my $result = $mat_results->[$i][$j];
push( @values1, $value1 );
push( @values2, $value2 );
push( @results, $result );
}
}
print "\n#ifndef __DATASET_H";
print "\n#define __DATASET_H";
print "\n\#define ARRAY_SIZE ".($opts{"size"}*$opts{"size"})." \n\n";
print "\n\#define DIM_SIZE ".$opts{"size"}." \n\n";
print "\ntypedef int data_t;";
printArray( "input1_data", \@values1 );
printArray( "input2_data", \@values2 );
printArray( "verify_data", \@results);
print "\n#endif //__DATASET_H";
}
main();

View file

@ -0,0 +1,57 @@
// See LICENSE for license details.
//**************************************************************************
// Multi-threaded Matrix Multiply benchmark
//--------------------------------------------------------------------------
// TA : Christopher Celio
// Student:
//
//
// This benchmark multiplies two 2-D arrays together and writes the results to
// a third vector. The input data (and reference data) should be generated
// using the matmul_gendata.pl perl script and dumped to a file named
// dataset.h.
//--------------------------------------------------------------------------
// Includes
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
//--------------------------------------------------------------------------
// Input/Reference Data
#include "dataset.h"
//--------------------------------------------------------------------------
// Basic Utilities and Multi-thread Support
#include "util.h"
//--------------------------------------------------------------------------
// matmul function
extern void matmul(const size_t coreid, const size_t ncores, const size_t lda, const data_t A[], const data_t B[], data_t C[] );
//--------------------------------------------------------------------------
// Main
//
// all threads start executing thread_entry(). Use their "coreid" to
// differentiate between threads (each thread is running on a separate core).
void thread_entry(int cid, int nc)
{
static data_t results_data[ARRAY_SIZE];
stats(matmul(cid, nc, DIM_SIZE, input1_data, input2_data, results_data); barrier(nc), DIM_SIZE/DIM_SIZE/DIM_SIZE);
int res = verify(ARRAY_SIZE, results_data, verify_data);
exit(res);
}

View file

@ -0,0 +1,173 @@
// See LICENSE for license details.
#ifndef __DATASET_H
#define __DATASET_H
#define DATA_SIZE 1000
typedef double data_t;
static data_t input1_data[DATA_SIZE] =
{
0.00, 15.00, 10.00, 3.00, 14.00, 6.00, 2.00, 18.00, 11.00, 15.00, 11.00, 0.00, 17.00, 16.00, 7.00, 13.00, 18.00, 2.00, 2.00, 5.00,
8.00, 5.00, 12.00, 14.00, 6.00, 12.00, 16.00, 7.00, 9.00, 17.00, 10.00, 10.00, 3.00, 5.00, 14.00, 11.00, 9.00, 12.00, 3.00, 1.00,
5.00, 4.00, 6.00, 17.00, 17.00, 4.00, 17.00, 15.00, 17.00, 18.00, 3.00, 18.00, 10.00, 6.00, 12.00, 12.00, 3.00, 2.00, 16.00, 1.00,
5.00, 6.00, 2.00, 17.00, 16.00, 5.00, 10.00, 18.00, 14.00, 4.00, 9.00, 9.00, 7.00, 4.00, 8.00, 13.00, 12.00, 6.00, 4.00, 17.00,
5.00, 2.00, 11.00, 11.00, 7.00, 6.00, 8.00, 5.00, 6.00, 6.00, 11.00, 1.00, 18.00, 7.00, 6.00, 9.00, 10.00, 17.00, 14.00, 4.00,
14.00, 11.00, 2.00, 0.00, 2.00, 17.00, 17.00, 15.00, 10.00, 8.00, 12.00, 18.00, 5.00, 0.00, 0.00, 1.00, 1.00, 8.00, 11.00, 11.00,
7.00, 5.00, 15.00, 18.00, 15.00, 6.00, 8.00, 9.00, 18.00, 6.00, 15.00, 16.00, 10.00, 18.00, 13.00, 6.00, 10.00, 16.00, 0.00, 10.00,
12.00, 8.00, 8.00, 3.00, 0.00, 1.00, 4.00, 0.00, 8.00, 15.00, 16.00, 9.00, 7.00, 7.00, 10.00, 9.00, 16.00, 12.00, 5.00, 5.00,
9.00, 5.00, 17.00, 4.00, 13.00, 13.00, 4.00, 14.00, 10.00, 5.00, 10.00, 10.00, 6.00, 18.00, 5.00, 15.00, 5.00, 15.00, 13.00, 18.00,
6.00, 13.00, 5.00, 18.00, 12.00, 14.00, 1.00, 7.00, 2.00, 1.00, 7.00, 12.00, 15.00, 15.00, 6.00, 2.00, 1.00, 2.00, 18.00, 6.00,
10.00, 14.00, 9.00, 15.00, 11.00, 0.00, 3.00, 1.00, 2.00, 2.00, 14.00, 7.00, 18.00, 0.00, 2.00, 2.00, 16.00, 8.00, 4.00, 5.00,
7.00, 11.00, 7.00, 10.00, 14.00, 10.00, 3.00, 0.00, 13.00, 9.00, 14.00, 0.00, 14.00, 1.00, 3.00, 16.00, 2.00, 14.00, 6.00, 17.00,
17.00, 6.00, 9.00, 8.00, 9.00, 12.00, 5.00, 14.00, 2.00, 16.00, 17.00, 5.00, 4.00, 0.00, 14.00, 10.00, 6.00, 15.00, 15.00, 14.00,
5.00, 1.00, 8.00, 8.00, 13.00, 8.00, 0.00, 4.00, 7.00, 9.00, 13.00, 16.00, 9.00, 14.00, 9.00, 13.00, 0.00, 7.00, 16.00, 17.00,
18.00, 10.00, 13.00, 8.00, 4.00, 9.00, 13.00, 0.00, 6.00, 4.00, 6.00, 4.00, 10.00, 14.00, 14.00, 9.00, 15.00, 15.00, 3.00, 3.00,
12.00, 0.00, 3.00, 2.00, 16.00, 1.00, 7.00, 2.00, 16.00, 2.00, 2.00, 0.00, 14.00, 3.00, 3.00, 10.00, 4.00, 10.00, 3.00, 4.00,
13.00, 14.00, 13.00, 0.00, 1.00, 15.00, 16.00, 9.00, 7.00, 9.00, 0.00, 11.00, 1.00, 1.00, 15.00, 17.00, 12.00, 16.00, 15.00, 4.00,
8.00, 2.00, 10.00, 10.00, 0.00, 18.00, 17.00, 7.00, 7.00, 2.00, 10.00, 17.00, 9.00, 7.00, 5.00, 3.00, 8.00, 11.00, 6.00, 9.00,
13.00, 0.00, 3.00, 5.00, 2.00, 5.00, 7.00, 4.00, 9.00, 2.00, 13.00, 17.00, 14.00, 12.00, 1.00, 3.00, 7.00, 17.00, 0.00, 14.00,
16.00, 2.00, 2.00, 1.00, 2.00, 15.00, 16.00, 8.00, 2.00, 4.00, 15.00, 15.00, 10.00, 6.00, 11.00, 9.00, 15.00, 17.00, 3.00, 8.00,
15.00, 3.00, 10.00, 15.00, 8.00, 14.00, 16.00, 15.00, 15.00, 14.00, 1.00, 7.00, 4.00, 18.00, 2.00, 13.00, 11.00, 15.00, 7.00, 10.00,
13.00, 10.00, 7.00, 14.00, 18.00, 4.00, 18.00, 4.00, 3.00, 9.00, 1.00, 13.00, 15.00, 2.00, 5.00, 15.00, 12.00, 10.00, 2.00, 0.00,
10.00, 15.00, 0.00, 11.00, 14.00, 11.00, 14.00, 9.00, 1.00, 18.00, 14.00, 18.00, 15.00, 5.00, 1.00, 15.00, 18.00, 14.00, 3.00, 15.00,
11.00, 2.00, 15.00, 0.00, 13.00, 1.00, 4.00, 14.00, 14.00, 5.00, 2.00, 13.00, 17.00, 8.00, 7.00, 6.00, 5.00, 10.00, 14.00, 14.00,
17.00, 0.00, 0.00, 17.00, 18.00, 15.00, 10.00, 16.00, 18.00, 5.00, 9.00, 10.00, 18.00, 7.00, 11.00, 5.00, 4.00, 16.00, 2.00, 8.00,
13.00, 1.00, 12.00, 3.00, 4.00, 6.00, 15.00, 12.00, 0.00, 6.00, 18.00, 12.00, 14.00, 18.00, 3.00, 2.00, 3.00, 5.00, 3.00, 14.00,
18.00, 12.00, 10.00, 11.00, 8.00, 4.00, 10.00, 10.00, 9.00, 18.00, 14.00, 3.00, 7.00, 17.00, 12.00, 0.00, 10.00, 9.00, 17.00, 3.00,
0.00, 4.00, 6.00, 16.00, 14.00, 12.00, 13.00, 13.00, 18.00, 7.00, 0.00, 1.00, 9.00, 7.00, 12.00, 6.00, 18.00, 8.00, 9.00, 13.00,
13.00, 17.00, 10.00, 16.00, 1.00, 10.00, 17.00, 16.00, 2.00, 18.00, 4.00, 2.00, 6.00, 1.00, 1.00, 1.00, 8.00, 14.00, 6.00, 6.00,
13.00, 14.00, 13.00, 6.00, 5.00, 10.00, 11.00, 11.00, 16.00, 1.00, 5.00, 9.00, 13.00, 8.00, 10.00, 2.00, 12.00, 15.00, 5.00, 14.00,
3.00, 7.00, 9.00, 18.00, 2.00, 11.00, 16.00, 4.00, 5.00, 10.00, 17.00, 10.00, 3.00, 4.00, 14.00, 18.00, 13.00, 6.00, 8.00, 11.00,
14.00, 3.00, 5.00, 6.00, 6.00, 5.00, 13.00, 0.00, 9.00, 9.00, 1.00, 7.00, 5.00, 5.00, 1.00, 6.00, 18.00, 11.00, 17.00, 7.00,
1.00, 10.00, 5.00, 12.00, 6.00, 16.00, 16.00, 5.00, 1.00, 10.00, 10.00, 15.00, 7.00, 18.00, 8.00, 17.00, 3.00, 5.00, 3.00, 14.00,
0.00, 16.00, 12.00, 0.00, 14.00, 17.00, 16.00, 2.00, 18.00, 13.00, 10.00, 13.00, 4.00, 14.00, 2.00, 3.00, 4.00, 8.00, 17.00, 0.00,
6.00, 11.00, 5.00, 3.00, 3.00, 2.00, 15.00, 13.00, 10.00, 4.00, 1.00, 11.00, 6.00, 17.00, 1.00, 0.00, 18.00, 3.00, 3.00, 11.00,
7.00, 7.00, 11.00, 14.00, 7.00, 16.00, 11.00, 10.00, 8.00, 6.00, 11.00, 5.00, 17.00, 10.00, 7.00, 8.00, 14.00, 2.00, 9.00, 17.00,
15.00, 13.00, 10.00, 6.00, 0.00, 15.00, 11.00, 10.00, 11.00, 18.00, 2.00, 5.00, 17.00, 18.00, 11.00, 15.00, 3.00, 17.00, 9.00, 17.00,
8.00, 6.00, 2.00, 4.00, 2.00, 11.00, 15.00, 2.00, 18.00, 3.00, 9.00, 7.00, 15.00, 9.00, 14.00, 10.00, 9.00, 6.00, 13.00, 8.00,
15.00, 14.00, 0.00, 11.00, 5.00, 2.00, 12.00, 14.00, 10.00, 16.00, 9.00, 7.00, 9.00, 17.00, 4.00, 4.00, 7.00, 8.00, 4.00, 4.00,
9.00, 7.00, 3.00, 5.00, 11.00, 11.00, 10.00, 13.00, 3.00, 14.00, 15.00, 8.00, 1.00, 1.00, 3.00, 0.00, 16.00, 9.00, 6.00, 1.00,
0.00, 2.00, 0.00, 6.00, 13.00, 12.00, 5.00, 18.00, 1.00, 11.00, 17.00, 11.00, 16.00, 14.00, 14.00, 9.00, 11.00, 9.00, 17.00, 15.00,
5.00, 18.00, 2.00, 11.00, 10.00, 16.00, 18.00, 5.00, 11.00, 12.00, 11.00, 18.00, 7.00, 6.00, 8.00, 3.00, 4.00, 3.00, 16.00, 4.00,
6.00, 2.00, 15.00, 6.00, 7.00, 16.00, 0.00, 7.00, 11.00, 10.00, 3.00, 0.00, 14.00, 16.00, 15.00, 15.00, 12.00, 7.00, 1.00, 4.00,
8.00, 4.00, 12.00, 0.00, 7.00, 8.00, 1.00, 1.00, 14.00, 15.00, 9.00, 8.00, 6.00, 6.00, 4.00, 7.00, 8.00, 13.00, 10.00, 5.00,
8.00, 11.00, 2.00, 16.00, 7.00, 17.00, 5.00, 2.00, 17.00, 0.00, 18.00, 6.00, 7.00, 4.00, 4.00, 12.00, 0.00, 18.00, 8.00, 4.00,
7.00, 0.00, 11.00, 1.00, 11.00, 17.00, 18.00, 15.00, 8.00, 11.00, 15.00, 9.00, 12.00, 1.00, 5.00, 6.00, 1.00, 18.00, 14.00, 7.00,
16.00, 16.00, 10.00, 3.00, 13.00, 0.00, 12.00, 9.00, 18.00, 14.00, 15.00, 4.00, 11.00, 15.00, 15.00, 8.00, 16.00, 11.00, 13.00, 12.00,
1.00, 13.00, 14.00, 2.00, 11.00, 0.00, 17.00, 11.00, 12.00, 6.00, 4.00, 4.00, 11.00, 13.00, 10.00, 2.00, 10.00, 14.00, 0.00, 6.00,
18.00, 10.00, 7.00, 14.00, 12.00, 9.00, 4.00, 16.00, 17.00, 8.00, 14.00, 9.00, 0.00, 4.00, 15.00, 13.00, 8.00, 13.00, 13.00, 8.00,
15.00, 6.00, 11.00, 4.00, 2.00, 6.00, 5.00, 14.00, 5.00, 17.00, 12.00, 11.00, 17.00, 4.00, 13.00, 7.00, 16.00, 12.00, 7.00, 18.00
};
static data_t input2_data[DATA_SIZE] =
{
8.00, 6.00, 0.00, 18.00, 6.00, 10.00, 1.00, 2.00, 4.00, 2.00, 4.00, 10.00, 6.00, 11.00, 17.00, 4.00, 0.00, 16.00, 14.00, 12.00,
9.00, 8.00, 13.00, 15.00, 18.00, 2.00, 13.00, 10.00, 5.00, 4.00, 12.00, 9.00, 1.00, 13.00, 12.00, 7.00, 10.00, 17.00, 11.00, 10.00,
18.00, 15.00, 11.00, 12.00, 7.00, 9.00, 6.00, 5.00, 11.00, 7.00, 10.00, 12.00, 18.00, 18.00, 15.00, 1.00, 3.00, 18.00, 11.00, 16.00,
13.00, 18.00, 4.00, 13.00, 8.00, 7.00, 10.00, 13.00, 0.00, 9.00, 1.00, 16.00, 13.00, 7.00, 5.00, 5.00, 11.00, 1.00, 6.00, 10.00,
12.00, 3.00, 10.00, 5.00, 15.00, 15.00, 13.00, 14.00, 14.00, 1.00, 18.00, 5.00, 16.00, 14.00, 10.00, 4.00, 8.00, 4.00, 6.00, 6.00,
13.00, 14.00, 8.00, 5.00, 14.00, 10.00, 9.00, 10.00, 17.00, 15.00, 6.00, 16.00, 12.00, 9.00, 10.00, 16.00, 16.00, 8.00, 1.00, 12.00,
7.00, 0.00, 0.00, 3.00, 5.00, 7.00, 10.00, 3.00, 17.00, 10.00, 18.00, 16.00, 1.00, 11.00, 18.00, 9.00, 2.00, 0.00, 12.00, 6.00,
13.00, 1.00, 13.00, 5.00, 7.00, 13.00, 17.00, 9.00, 15.00, 13.00, 5.00, 2.00, 4.00, 4.00, 3.00, 0.00, 9.00, 11.00, 3.00, 12.00,
6.00, 11.00, 1.00, 16.00, 12.00, 11.00, 2.00, 2.00, 15.00, 12.00, 8.00, 9.00, 14.00, 2.00, 11.00, 0.00, 0.00, 7.00, 2.00, 13.00,
15.00, 18.00, 7.00, 16.00, 16.00, 1.00, 1.00, 12.00, 12.00, 2.00, 2.00, 1.00, 7.00, 4.00, 0.00, 8.00, 18.00, 4.00, 11.00, 6.00,
17.00, 13.00, 12.00, 5.00, 16.00, 12.00, 0.00, 9.00, 10.00, 10.00, 18.00, 12.00, 8.00, 7.00, 5.00, 8.00, 16.00, 3.00, 9.00, 18.00,
12.00, 13.00, 18.00, 6.00, 8.00, 12.00, 2.00, 12.00, 8.00, 8.00, 9.00, 18.00, 8.00, 0.00, 9.00, 2.00, 6.00, 7.00, 0.00, 3.00,
11.00, 2.00, 18.00, 2.00, 16.00, 1.00, 16.00, 11.00, 11.00, 16.00, 16.00, 11.00, 7.00, 4.00, 14.00, 10.00, 5.00, 8.00, 4.00, 14.00,
17.00, 13.00, 13.00, 3.00, 1.00, 14.00, 1.00, 7.00, 0.00, 2.00, 7.00, 14.00, 4.00, 9.00, 14.00, 3.00, 9.00, 13.00, 13.00, 3.00,
3.00, 17.00, 0.00, 18.00, 4.00, 8.00, 6.00, 9.00, 4.00, 2.00, 0.00, 14.00, 3.00, 3.00, 14.00, 8.00, 6.00, 7.00, 2.00, 12.00,
5.00, 14.00, 6.00, 12.00, 2.00, 16.00, 1.00, 15.00, 7.00, 18.00, 0.00, 0.00, 13.00, 13.00, 12.00, 11.00, 16.00, 15.00, 14.00, 8.00,
9.00, 10.00, 8.00, 8.00, 13.00, 13.00, 13.00, 10.00, 1.00, 15.00, 4.00, 0.00, 12.00, 1.00, 8.00, 12.00, 1.00, 18.00, 12.00, 18.00,
9.00, 1.00, 11.00, 5.00, 13.00, 7.00, 1.00, 13.00, 5.00, 8.00, 17.00, 11.00, 13.00, 15.00, 9.00, 3.00, 17.00, 18.00, 9.00, 3.00,
15.00, 11.00, 12.00, 0.00, 2.00, 15.00, 3.00, 0.00, 13.00, 1.00, 14.00, 14.00, 15.00, 8.00, 6.00, 0.00, 0.00, 11.00, 17.00, 0.00,
1.00, 8.00, 6.00, 6.00, 10.00, 6.00, 18.00, 12.00, 7.00, 18.00, 4.00, 6.00, 15.00, 18.00, 7.00, 5.00, 8.00, 6.00, 6.00, 7.00,
4.00, 4.00, 10.00, 17.00, 12.00, 13.00, 11.00, 15.00, 12.00, 18.00, 7.00, 12.00, 17.00, 10.00, 14.00, 12.00, 2.00, 7.00, 17.00, 3.00,
8.00, 6.00, 3.00, 9.00, 3.00, 7.00, 7.00, 15.00, 18.00, 5.00, 13.00, 13.00, 15.00, 10.00, 0.00, 11.00, 10.00, 1.00, 5.00, 16.00,
2.00, 7.00, 14.00, 12.00, 7.00, 17.00, 17.00, 11.00, 0.00, 5.00, 16.00, 14.00, 1.00, 9.00, 8.00, 8.00, 3.00, 17.00, 0.00, 8.00,
6.00, 5.00, 7.00, 6.00, 17.00, 3.00, 3.00, 8.00, 3.00, 12.00, 17.00, 5.00, 14.00, 3.00, 11.00, 5.00, 17.00, 2.00, 15.00, 1.00,
18.00, 11.00, 12.00, 0.00, 0.00, 14.00, 7.00, 17.00, 15.00, 10.00, 18.00, 10.00, 11.00, 7.00, 12.00, 10.00, 17.00, 2.00, 18.00, 9.00,
11.00, 4.00, 17.00, 10.00, 15.00, 12.00, 4.00, 1.00, 5.00, 10.00, 4.00, 2.00, 11.00, 3.00, 4.00, 15.00, 16.00, 10.00, 2.00, 2.00,
15.00, 16.00, 0.00, 13.00, 16.00, 9.00, 1.00, 7.00, 3.00, 10.00, 7.00, 2.00, 12.00, 8.00, 1.00, 5.00, 0.00, 16.00, 4.00, 14.00,
13.00, 16.00, 3.00, 0.00, 10.00, 6.00, 3.00, 9.00, 1.00, 3.00, 0.00, 13.00, 12.00, 17.00, 11.00, 4.00, 15.00, 15.00, 12.00, 4.00,
4.00, 2.00, 16.00, 6.00, 11.00, 17.00, 14.00, 7.00, 4.00, 14.00, 8.00, 8.00, 3.00, 18.00, 17.00, 17.00, 12.00, 10.00, 11.00, 1.00,
8.00, 13.00, 1.00, 14.00, 0.00, 9.00, 0.00, 7.00, 9.00, 0.00, 7.00, 12.00, 0.00, 18.00, 10.00, 1.00, 5.00, 13.00, 13.00, 2.00,
10.00, 4.00, 2.00, 6.00, 0.00, 16.00, 2.00, 15.00, 13.00, 6.00, 8.00, 5.00, 6.00, 15.00, 12.00, 6.00, 6.00, 7.00, 8.00, 1.00,
11.00, 9.00, 7.00, 18.00, 14.00, 4.00, 9.00, 6.00, 4.00, 2.00, 10.00, 13.00, 6.00, 17.00, 2.00, 11.00, 7.00, 3.00, 8.00, 9.00,
2.00, 6.00, 18.00, 12.00, 18.00, 13.00, 8.00, 1.00, 11.00, 4.00, 13.00, 14.00, 16.00, 8.00, 6.00, 18.00, 14.00, 15.00, 9.00, 11.00,
2.00, 13.00, 4.00, 3.00, 3.00, 15.00, 14.00, 3.00, 13.00, 12.00, 14.00, 16.00, 18.00, 12.00, 5.00, 11.00, 2.00, 3.00, 15.00, 1.00,
12.00, 1.00, 15.00, 13.00, 12.00, 18.00, 4.00, 17.00, 13.00, 7.00, 11.00, 13.00, 7.00, 10.00, 1.00, 3.00, 18.00, 6.00, 10.00, 3.00,
9.00, 16.00, 12.00, 10.00, 6.00, 6.00, 7.00, 16.00, 16.00, 16.00, 17.00, 18.00, 8.00, 18.00, 0.00, 6.00, 17.00, 13.00, 14.00, 8.00,
0.00, 7.00, 5.00, 13.00, 8.00, 12.00, 14.00, 9.00, 10.00, 10.00, 9.00, 9.00, 8.00, 6.00, 0.00, 14.00, 16.00, 8.00, 7.00, 16.00,
10.00, 3.00, 1.00, 9.00, 11.00, 2.00, 6.00, 18.00, 5.00, 4.00, 2.00, 11.00, 10.00, 17.00, 16.00, 2.00, 12.00, 15.00, 14.00, 6.00,
6.00, 17.00, 3.00, 10.00, 9.00, 18.00, 18.00, 6.00, 11.00, 16.00, 18.00, 17.00, 7.00, 14.00, 1.00, 16.00, 7.00, 9.00, 11.00, 12.00,
10.00, 6.00, 1.00, 16.00, 9.00, 18.00, 0.00, 9.00, 16.00, 10.00, 14.00, 6.00, 9.00, 14.00, 15.00, 7.00, 12.00, 8.00, 1.00, 1.00,
1.00, 17.00, 17.00, 17.00, 18.00, 1.00, 15.00, 18.00, 16.00, 16.00, 11.00, 7.00, 4.00, 15.00, 3.00, 14.00, 13.00, 14.00, 9.00, 2.00,
4.00, 8.00, 14.00, 7.00, 0.00, 12.00, 14.00, 15.00, 8.00, 2.00, 11.00, 5.00, 6.00, 16.00, 6.00, 4.00, 16.00, 7.00, 9.00, 5.00,
1.00, 0.00, 16.00, 10.00, 9.00, 6.00, 5.00, 8.00, 15.00, 13.00, 7.00, 18.00, 18.00, 8.00, 0.00, 15.00, 4.00, 6.00, 14.00, 3.00,
3.00, 2.00, 9.00, 14.00, 18.00, 13.00, 10.00, 15.00, 0.00, 11.00, 16.00, 7.00, 16.00, 18.00, 0.00, 12.00, 6.00, 13.00, 12.00, 12.00,
5.00, 3.00, 5.00, 16.00, 13.00, 16.00, 8.00, 5.00, 12.00, 8.00, 8.00, 0.00, 2.00, 9.00, 18.00, 11.00, 8.00, 4.00, 14.00, 6.00,
17.00, 2.00, 6.00, 8.00, 11.00, 13.00, 6.00, 18.00, 17.00, 6.00, 8.00, 0.00, 1.00, 14.00, 18.00, 4.00, 0.00, 4.00, 3.00, 3.00,
16.00, 8.00, 16.00, 1.00, 2.00, 0.00, 15.00, 14.00, 10.00, 9.00, 15.00, 3.00, 5.00, 18.00, 5.00, 6.00, 7.00, 3.00, 7.00, 2.00,
6.00, 12.00, 10.00, 10.00, 18.00, 16.00, 0.00, 9.00, 17.00, 10.00, 9.00, 14.00, 15.00, 5.00, 8.00, 15.00, 3.00, 15.00, 14.00, 11.00,
6.00, 6.00, 14.00, 0.00, 14.00, 0.00, 7.00, 12.00, 8.00, 7.00, 1.00, 3.00, 6.00, 10.00, 12.00, 1.00, 16.00, 5.00, 5.00, 6.00,
17.00, 15.00, 15.00, 9.00, 4.00, 18.00, 17.00, 13.00, 12.00, 9.00, 7.00, 10.00, 2.00, 5.00, 8.00, 18.00, 1.00, 15.00, 8.00, 0.00
};
static data_t verify_data[DATA_SIZE] =
{
8.00, 21.00, 10.00, 21.00, 20.00, 16.00, 3.00, 20.00, 15.00, 17.00, 15.00, 10.00, 23.00, 27.00, 24.00, 17.00, 18.00, 18.00, 16.00, 17.00,
17.00, 13.00, 25.00, 29.00, 24.00, 14.00, 29.00, 17.00, 14.00, 21.00, 22.00, 19.00, 4.00, 18.00, 26.00, 18.00, 19.00, 29.00, 14.00, 11.00,
23.00, 19.00, 17.00, 29.00, 24.00, 13.00, 23.00, 20.00, 28.00, 25.00, 13.00, 30.00, 28.00, 24.00, 27.00, 13.00, 6.00, 20.00, 27.00, 17.00,
18.00, 24.00, 6.00, 30.00, 24.00, 12.00, 20.00, 31.00, 14.00, 13.00, 10.00, 25.00, 20.00, 11.00, 13.00, 18.00, 23.00, 7.00, 10.00, 27.00,
17.00, 5.00, 21.00, 16.00, 22.00, 21.00, 21.00, 19.00, 20.00, 7.00, 29.00, 6.00, 34.00, 21.00, 16.00, 13.00, 18.00, 21.00, 20.00, 10.00,
27.00, 25.00, 10.00, 5.00, 16.00, 27.00, 26.00, 25.00, 27.00, 23.00, 18.00, 34.00, 17.00, 9.00, 10.00, 17.00, 17.00, 16.00, 12.00, 23.00,
14.00, 5.00, 15.00, 21.00, 20.00, 13.00, 18.00, 12.00, 35.00, 16.00, 33.00, 32.00, 11.00, 29.00, 31.00, 15.00, 12.00, 16.00, 12.00, 16.00,
25.00, 9.00, 21.00, 8.00, 7.00, 14.00, 21.00, 9.00, 23.00, 28.00, 21.00, 11.00, 11.00, 11.00, 13.00, 9.00, 25.00, 23.00, 8.00, 17.00,
15.00, 16.00, 18.00, 20.00, 25.00, 24.00, 6.00, 16.00, 25.00, 17.00, 18.00, 19.00, 20.00, 20.00, 16.00, 15.00, 5.00, 22.00, 15.00, 31.00,
21.00, 31.00, 12.00, 34.00, 28.00, 15.00, 2.00, 19.00, 14.00, 3.00, 9.00, 13.00, 22.00, 19.00, 6.00, 10.00, 19.00, 6.00, 29.00, 12.00,
27.00, 27.00, 21.00, 20.00, 27.00, 12.00, 3.00, 10.00, 12.00, 12.00, 32.00, 19.00, 26.00, 7.00, 7.00, 10.00, 32.00, 11.00, 13.00, 23.00,
19.00, 24.00, 25.00, 16.00, 22.00, 22.00, 5.00, 12.00, 21.00, 17.00, 23.00, 18.00, 22.00, 1.00, 12.00, 18.00, 8.00, 21.00, 6.00, 20.00,
28.00, 8.00, 27.00, 10.00, 25.00, 13.00, 21.00, 25.00, 13.00, 32.00, 33.00, 16.00, 11.00, 4.00, 28.00, 20.00, 11.00, 23.00, 19.00, 28.00,
22.00, 14.00, 21.00, 11.00, 14.00, 22.00, 1.00, 11.00, 7.00, 11.00, 20.00, 30.00, 13.00, 23.00, 23.00, 16.00, 9.00, 20.00, 29.00, 20.00,
21.00, 27.00, 13.00, 26.00, 8.00, 17.00, 19.00, 9.00, 10.00, 6.00, 6.00, 18.00, 13.00, 17.00, 28.00, 17.00, 21.00, 22.00, 5.00, 15.00,
17.00, 14.00, 9.00, 14.00, 18.00, 17.00, 8.00, 17.00, 23.00, 20.00, 2.00, 0.00, 27.00, 16.00, 15.00, 21.00, 20.00, 25.00, 17.00, 12.00,
22.00, 24.00, 21.00, 8.00, 14.00, 28.00, 29.00, 19.00, 8.00, 24.00, 4.00, 11.00, 13.00, 2.00, 23.00, 29.00, 13.00, 34.00, 27.00, 22.00,
17.00, 3.00, 21.00, 15.00, 13.00, 25.00, 18.00, 20.00, 12.00, 10.00, 27.00, 28.00, 22.00, 22.00, 14.00, 6.00, 25.00, 29.00, 15.00, 12.00,
28.00, 11.00, 15.00, 5.00, 4.00, 20.00, 10.00, 4.00, 22.00, 3.00, 27.00, 31.00, 29.00, 20.00, 7.00, 3.00, 7.00, 28.00, 17.00, 14.00,
17.00, 10.00, 8.00, 7.00, 12.00, 21.00, 34.00, 20.00, 9.00, 22.00, 19.00, 21.00, 25.00, 24.00, 18.00, 14.00, 23.00, 23.00, 9.00, 15.00,
19.00, 7.00, 20.00, 32.00, 20.00, 27.00, 27.00, 30.00, 27.00, 32.00, 8.00, 19.00, 21.00, 28.00, 16.00, 25.00, 13.00, 22.00, 24.00, 13.00,
21.00, 16.00, 10.00, 23.00, 21.00, 11.00, 25.00, 19.00, 21.00, 14.00, 14.00, 26.00, 30.00, 12.00, 5.00, 26.00, 22.00, 11.00, 7.00, 16.00,
12.00, 22.00, 14.00, 23.00, 21.00, 28.00, 31.00, 20.00, 1.00, 23.00, 30.00, 32.00, 16.00, 14.00, 9.00, 23.00, 21.00, 31.00, 3.00, 23.00,
17.00, 7.00, 22.00, 6.00, 30.00, 4.00, 7.00, 22.00, 17.00, 17.00, 19.00, 18.00, 31.00, 11.00, 18.00, 11.00, 22.00, 12.00, 29.00, 15.00,
35.00, 11.00, 12.00, 17.00, 18.00, 29.00, 17.00, 33.00, 33.00, 15.00, 27.00, 20.00, 29.00, 14.00, 23.00, 15.00, 21.00, 18.00, 20.00, 17.00,
24.00, 5.00, 29.00, 13.00, 19.00, 18.00, 19.00, 13.00, 5.00, 16.00, 22.00, 14.00, 25.00, 21.00, 7.00, 17.00, 19.00, 15.00, 5.00, 16.00,
33.00, 28.00, 10.00, 24.00, 24.00, 13.00, 11.00, 17.00, 12.00, 28.00, 21.00, 5.00, 19.00, 25.00, 13.00, 5.00, 10.00, 25.00, 21.00, 17.00,
13.00, 20.00, 9.00, 16.00, 24.00, 18.00, 16.00, 22.00, 19.00, 10.00, 0.00, 14.00, 21.00, 24.00, 23.00, 10.00, 33.00, 23.00, 21.00, 17.00,
17.00, 19.00, 26.00, 22.00, 12.00, 27.00, 31.00, 23.00, 6.00, 32.00, 12.00, 10.00, 9.00, 19.00, 18.00, 18.00, 20.00, 24.00, 17.00, 7.00,
21.00, 27.00, 14.00, 20.00, 5.00, 19.00, 11.00, 18.00, 25.00, 1.00, 12.00, 21.00, 13.00, 26.00, 20.00, 3.00, 17.00, 28.00, 18.00, 16.00,
13.00, 11.00, 11.00, 24.00, 2.00, 27.00, 18.00, 19.00, 18.00, 16.00, 25.00, 15.00, 9.00, 19.00, 26.00, 24.00, 19.00, 13.00, 16.00, 12.00,
25.00, 12.00, 12.00, 24.00, 20.00, 9.00, 22.00, 6.00, 13.00, 11.00, 11.00, 20.00, 11.00, 22.00, 3.00, 17.00, 25.00, 14.00, 25.00, 16.00,
3.00, 16.00, 23.00, 24.00, 24.00, 29.00, 24.00, 6.00, 12.00, 14.00, 23.00, 29.00, 23.00, 26.00, 14.00, 35.00, 17.00, 20.00, 12.00, 25.00,
2.00, 29.00, 16.00, 3.00, 17.00, 32.00, 30.00, 5.00, 31.00, 25.00, 24.00, 29.00, 22.00, 26.00, 7.00, 14.00, 6.00, 11.00, 32.00, 1.00,
18.00, 12.00, 20.00, 16.00, 15.00, 20.00, 19.00, 30.00, 23.00, 11.00, 12.00, 24.00, 13.00, 27.00, 2.00, 3.00, 36.00, 9.00, 13.00, 14.00,
16.00, 23.00, 23.00, 24.00, 13.00, 22.00, 18.00, 26.00, 24.00, 22.00, 28.00, 23.00, 25.00, 28.00, 7.00, 14.00, 31.00, 15.00, 23.00, 25.00,
15.00, 20.00, 15.00, 19.00, 8.00, 27.00, 25.00, 19.00, 21.00, 28.00, 11.00, 14.00, 25.00, 24.00, 11.00, 29.00, 19.00, 25.00, 16.00, 33.00,
18.00, 9.00, 3.00, 13.00, 13.00, 13.00, 21.00, 20.00, 23.00, 7.00, 11.00, 18.00, 25.00, 26.00, 30.00, 12.00, 21.00, 21.00, 27.00, 14.00,
21.00, 31.00, 3.00, 21.00, 14.00, 20.00, 30.00, 20.00, 21.00, 32.00, 27.00, 24.00, 16.00, 31.00, 5.00, 20.00, 14.00, 17.00, 15.00, 16.00,
19.00, 13.00, 4.00, 21.00, 20.00, 29.00, 10.00, 22.00, 19.00, 24.00, 29.00, 14.00, 10.00, 15.00, 18.00, 7.00, 28.00, 17.00, 7.00, 2.00,
1.00, 19.00, 17.00, 23.00, 31.00, 13.00, 20.00, 36.00, 17.00, 27.00, 28.00, 18.00, 20.00, 29.00, 17.00, 23.00, 24.00, 23.00, 26.00, 17.00,
9.00, 26.00, 16.00, 18.00, 10.00, 28.00, 32.00, 20.00, 19.00, 14.00, 22.00, 23.00, 13.00, 22.00, 14.00, 7.00, 20.00, 10.00, 25.00, 9.00,
7.00, 2.00, 31.00, 16.00, 16.00, 22.00, 5.00, 15.00, 26.00, 23.00, 10.00, 18.00, 32.00, 24.00, 15.00, 30.00, 16.00, 13.00, 15.00, 7.00,
11.00, 6.00, 21.00, 14.00, 25.00, 21.00, 11.00, 16.00, 14.00, 26.00, 25.00, 15.00, 22.00, 24.00, 4.00, 19.00, 14.00, 26.00, 22.00, 17.00,
13.00, 14.00, 7.00, 32.00, 20.00, 33.00, 13.00, 7.00, 29.00, 8.00, 26.00, 6.00, 9.00, 13.00, 22.00, 23.00, 8.00, 22.00, 22.00, 10.00,
24.00, 2.00, 17.00, 9.00, 22.00, 30.00, 24.00, 33.00, 25.00, 17.00, 23.00, 9.00, 13.00, 15.00, 23.00, 10.00, 1.00, 22.00, 17.00, 10.00,
32.00, 24.00, 26.00, 4.00, 15.00, 0.00, 27.00, 23.00, 28.00, 23.00, 30.00, 7.00, 16.00, 33.00, 20.00, 14.00, 23.00, 14.00, 20.00, 14.00,
7.00, 25.00, 24.00, 12.00, 29.00, 16.00, 17.00, 20.00, 29.00, 16.00, 13.00, 18.00, 26.00, 18.00, 18.00, 17.00, 13.00, 29.00, 14.00, 17.00,
24.00, 16.00, 21.00, 14.00, 26.00, 9.00, 11.00, 28.00, 25.00, 15.00, 15.00, 12.00, 6.00, 14.00, 27.00, 14.00, 24.00, 18.00, 18.00, 14.00,
32.00, 21.00, 26.00, 13.00, 6.00, 24.00, 22.00, 27.00, 17.00, 26.00, 19.00, 21.00, 19.00, 9.00, 21.00, 25.00, 17.00, 27.00, 15.00, 18.00
};
#endif //__DATASET_H

View file

@ -0,0 +1,78 @@
// See LICENSE for license details.
//**************************************************************************
// Vector-vector add benchmark
//--------------------------------------------------------------------------
// Author : Andrew Waterman
// TA : Christopher Celio
// Student :
//
// This benchmark adds two vectors and writes the results to a
// third vector. The input data (and reference data) should be
// generated using the vvadd_gendata.pl perl script and dumped
// to a file named dataset.h
//--------------------------------------------------------------------------
// Includes
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
//--------------------------------------------------------------------------
// Input/Reference Data
#include "dataset.h"
//--------------------------------------------------------------------------
// Basic Utilities and Multi-thread Support
#include "util.h"
//--------------------------------------------------------------------------
// vvadd function
extern void __attribute__((noinline)) vvadd(int coreid, int ncores, size_t n, const data_t* x, const data_t* y, data_t* z);
//--------------------------------------------------------------------------
// Main
//
// all threads start executing thread_entry(). Use their "coreid" to
// differentiate between threads (each thread is running on a separate core).
void thread_entry(int cid, int nc)
{
// static allocates data in the binary, which is visible to both threads
static data_t results_data[DATA_SIZE];
// First do out-of-place vvadd
barrier(nc);
stats(vvadd(cid, nc, DATA_SIZE, input1_data, input2_data, results_data); barrier(nc), DATA_SIZE);
if(cid == 0) {
int res = verifyDouble(DATA_SIZE, results_data, verify_data);
if(res) exit(res);
}
// Second do in-place vvadd
// Copying input
size_t i;
if(cid == 0) {
for (i = 0; i < DATA_SIZE; i++)
results_data[i] = input1_data[i];
}
barrier(nc);
stats(vvadd(cid, nc, DATA_SIZE, results_data, input2_data, results_data); barrier(nc), DATA_SIZE);
if(cid == 0) {
int res = verifyDouble(DATA_SIZE, results_data, verify_data);
if(res) exit(res);
}
barrier(nc);
exit(0);
}

View file

@ -0,0 +1,18 @@
// See LICENSE for license details.
#include "stdlib.h"
#include "dataset.h"
//--------------------------------------------------------------------------
// vvadd function
void __attribute__((noinline)) vvadd(int coreid, int ncores, size_t n, const data_t* x, const data_t* y, data_t* z)
{
size_t i;
// interleave accesses
for (i = coreid; i < n; i+=ncores)
{
z[i] = x[i] + y[i];
}
}

View file

@ -0,0 +1,139 @@
#!/usr/bin/perl -w
#==========================================================================
# vvadd_gendata.pl
#
# Author : Christopher Batten (cbatten@mit.edu)
# Date : April 29, 2005
#
(our $usageMsg = <<'ENDMSG') =~ s/^\#//gm;
#
# Simple script which creates an input data set and the reference data
# for the vvadd benchmark.
#
ENDMSG
use strict "vars";
use warnings;
no warnings("once");
use Getopt::Long;
#--------------------------------------------------------------------------
# Command line processing
#--------------------------------------------------------------------------
our %opts;
sub usage()
{
print "\n";
print " Usage: vvadd_gendata.pl [options] \n";
print "\n";
print " Options:\n";
print " --help print this message\n";
print " --size size of input data [1000]\n";
print " --seed random seed [1]\n";
print "$usageMsg";
exit();
}
sub processCommandLine()
{
$opts{"help"} = 0;
$opts{"size"} = 1000;
$opts{"seed"} = 1;
Getopt::Long::GetOptions( \%opts, 'help|?', 'size:i', 'seed:i' ) or usage();
$opts{"help"} and usage();
}
#--------------------------------------------------------------------------
# Helper Functions
#--------------------------------------------------------------------------
sub printArray
{
my $arrayName = $_[0];
my $arrayRef = $_[1];
my $numCols = 20;
my $arrayLen = scalar(@{$arrayRef});
print "static data_t ".$arrayName."[DATA_SIZE] = \n";
print "{\n";
if ( $arrayLen <= $numCols ) {
print " ";
for ( my $i = 0; $i < $arrayLen; $i++ ) {
print sprintf("%3.2f",$arrayRef->[$i]);
if ( $i != $arrayLen-1 ) {
print ", ";
}
}
print "\n";
}
else {
my $numRows = int($arrayLen/$numCols);
for ( my $j = 0; $j < $numRows; $j++ ) {
print " ";
for ( my $i = 0; $i < $numCols; $i++ ) {
my $index = $j*$numCols + $i;
print sprintf("%3.2f",$arrayRef->[$index]);
if ( $index != $arrayLen-1 ) {
print ", ";
}
}
print "\n";
}
if ( $arrayLen > ($numRows*$numCols) ) {
print " ";
for ( my $i = 0; $i < ($arrayLen-($numRows*$numCols)); $i++ ) {
my $index = $numCols*$numRows + $i;
print sprintf("%3.2f",$arrayRef->[$index]);
if ( $index != $arrayLen-1 ) {
print ", ";
}
}
print "\n";
}
}
print "};\n\n";
}
#--------------------------------------------------------------------------
# Main
#--------------------------------------------------------------------------
sub main()
{
processCommandLine();
srand($opts{"seed"});
my @values1;
my @values2;
my @sum;
for ( my $i = 0; $i < $opts{"size"}; $i++ ) {
my $value1 = int(rand(19));
my $value2 = int(rand(19));
push( @values1, $value1 );
push( @values2, $value2 );
push( @sum, $value1 + $value2 );
}
print "\n\#define DATA_SIZE ".$opts{"size"}." \n\n";
printArray( "input1_data", \@values1 );
printArray( "input2_data", \@values2 );
printArray( "verify_data", \@sum );
}
main();

View file

@ -0,0 +1,32 @@
// See LICENSE for license details.
#define DATA_SIZE 100
int input_data1[DATA_SIZE] =
{
41, 454, 833, 335, 564, 1, 187, 989, 749, 365, 350, 572, 132, 64, 949, 153, 584, 216, 805, 140,
621, 210, 6, 572, 931, 339, 890, 593, 392, 898, 694, 228, 961, 12, 110, 883, 116, 750, 296, 646,
426, 500, 314, 436, 659, 701, 774, 812, 319, 981, 678, 150, 875, 696, 376, 564, 474, 272, 938, 258,
539, 647, 569, 509, 203, 88, 280, 703, 759, 669, 606, 375, 511, 551, 657, 936, 195, 592, 81, 569,
267, 952, 229, 800, 337, 584, 944, 643, 902, 368, 241, 489, 913, 328, 826, 313, 933, 592, 985, 388
};
int input_data2[DATA_SIZE] =
{
195, 543, 960, 649, 566, 979, 350, 997, 649, 814, 657, 79, 181, 208, 111, 998, 859, 629, 65, 847,
288, 704, 349, 997, 141, 253, 905, 715, 886, 430, 264, 415, 576, 538, 979, 700, 761, 4, 241, 494,
478, 100, 499, 864, 403, 693, 222, 416, 444, 296, 721, 285, 676, 620, 317, 78, 224, 351, 937, 540,
288, 646, 119, 169, 615, 527, 606, 289, 389, 796, 351, 801, 455, 720, 278, 758, 367, 745, 358, 92,
584, 989, 62, 271, 985, 853, 403, 788, 346, 531, 517, 222, 559, 461, 908, 241, 775, 358, 255, 332
};
int verify_data[DATA_SIZE] =
{
7995, 246522, 799680, 217415, 319224, 979, 65450, 986033, 486101, 297110, 229950, 45188, 23892, 13312, 105339, 152694, 501656, 135864, 52325, 118580,
178848, 147840, 2094, 570284, 131271, 85767, 805450, 423995, 347312, 386140, 183216, 94620, 553536, 6456, 107690, 618100, 88276, 3000, 71336, 319124,
203628, 50000, 156686, 376704, 265577, 485793, 171828, 337792, 141636, 290376, 488838, 42750, 591500, 431520, 119192, 43992, 106176, 95472, 878906, 139320,
155232, 417962, 67711, 86021, 124845, 46376, 169680, 203167, 295251, 532524, 212706, 300375, 232505, 396720, 182646, 709488, 71565, 441040, 28998, 52348,
155928, 941528, 14198, 216800, 331945, 498152, 380432, 506684, 312092, 195408, 124597, 108558, 510367, 151208, 750008, 75433, 723075, 211936, 251175, 128816
};

View file

@ -0,0 +1,24 @@
// See LICENSE for license details.
// *************************************************************************
// multiply function (c version)
// -------------------------------------------------------------------------
int multiply( int x, int y )
{
int i;
int result = 0;
for (i = 0; i < 32; i++) {
if ((x & 0x1) == 1)
result = result + y;
x = x >> 1;
y = y << 1;
}
return result;
}

View file

@ -0,0 +1,11 @@
// See LICENSE for license details.
//**************************************************************************
// Software multiply function
//--------------------------------------------------------------------------
// Simple C version
int multiply(int x, int y);
// Simple assembly version
int multiply_asm(int x, int y);

View file

@ -0,0 +1,142 @@
#!/usr/bin/perl -w
#==========================================================================
# multiply_gendata.pl
#
# Author : Christopher Batten (cbatten@mit.edu)
# Date : May 9, 2005
#
(our $usageMsg = <<'ENDMSG') =~ s/^\#//gm;
#
# Simple script which creates an input data set and the reference data
# for the multiply benchmark.
#
ENDMSG
use strict "vars";
use warnings;
no warnings("once");
use Getopt::Long;
#--------------------------------------------------------------------------
# Command line processing
#--------------------------------------------------------------------------
our %opts;
sub usage()
{
print "\n";
print " Usage: multiply_gendata.pl [options] \n";
print "\n";
print " Options:\n";
print " --help print this message\n";
print " --size size of input data [750]\n";
print " --seed random seed [1]\n";
print "$usageMsg";
exit();
}
sub processCommandLine()
{
$opts{"help"} = 0;
$opts{"size"} = 750;
$opts{"seed"} = 1;
Getopt::Long::GetOptions( \%opts, 'help|?', 'size:i', 'seed:i' ) or usage();
$opts{"help"} and usage();
}
#--------------------------------------------------------------------------
# Helper Functions
#--------------------------------------------------------------------------
sub printArray
{
my $arrayName = $_[0];
my $arrayRef = $_[1];
my $numCols = 20;
my $arrayLen = scalar(@{$arrayRef});
print "int ".$arrayName."[DATA_SIZE] = \n";
print "{\n";
if ( $arrayLen <= $numCols ) {
print " ";
for ( my $i = 0; $i < $arrayLen; $i++ ) {
print sprintf("%3d",$arrayRef->[$i]);
if ( $i != $arrayLen-1 ) {
print ", ";
}
}
print "\n";
}
else {
my $numRows = int($arrayLen/$numCols);
for ( my $j = 0; $j < $numRows; $j++ ) {
print " ";
for ( my $i = 0; $i < $numCols; $i++ ) {
my $index = $j*$numCols + $i;
print sprintf("%3d",$arrayRef->[$index]);
if ( $index != $arrayLen-1 ) {
print ", ";
}
}
print "\n";
}
if ( $arrayLen > ($numRows*$numCols) ) {
print " ";
for ( my $i = 0; $i < ($arrayLen-($numRows*$numCols)); $i++ ) {
my $index = $numCols*$numRows + $i;
print sprintf("%3d",$arrayRef->[$index]);
if ( $index != $arrayLen-1 ) {
print ", ";
}
}
print "\n";
}
}
print "};\n\n";
}
#--------------------------------------------------------------------------
# Main
#--------------------------------------------------------------------------
sub main()
{
processCommandLine();
srand($opts{"seed"});
my @values1;
for ( my $i = 0; $i < $opts{"size"}; $i++ ) {
push( @values1, int(rand(999)) );
}
my @values2;
for ( my $i = 0; $i < $opts{"size"}; $i++ ) {
push( @values2, int(rand(999)) );
}
my @multiply;
for ( my $i = 0; $i < $opts{"size"}; $i++ ) {
$multiply[$i] = $values1[$i] * $values2[$i];
}
print "\n\#define DATA_SIZE ".$opts{"size"}." \n\n";
printArray( "input_data1", \@values1 );
printArray( "input_data2", \@values2 );
printArray( "verify_data", \@multiply );
}
main();

View file

@ -0,0 +1,45 @@
// See LICENSE for license details.
// *************************************************************************
// multiply filter bencmark
// -------------------------------------------------------------------------
//
// This benchmark tests the software multiply implemenation. The
// input data (and reference data) should be generated using the
// multiply_gendata.pl perl script and dumped to a file named
// dataset1.h
#include "util.h"
#include "multiply.h"
//--------------------------------------------------------------------------
// Input/Reference Data
#include "dataset1.h"
//--------------------------------------------------------------------------
// Main
int main( int argc, char* argv[] )
{
int i;
int results_data[DATA_SIZE];
#if PREALLOCATE
for (i = 0; i < DATA_SIZE; i++)
{
results_data[i] = multiply( input_data1[i], input_data2[i] );
}
#endif
setStats(1);
for (i = 0; i < DATA_SIZE; i++)
{
results_data[i] = multiply( input_data1[i], input_data2[i] );
}
setStats(0);
// Check the results
return verify( DATA_SIZE, results_data, verify_data );
}

212
vendor/riscv-tests/benchmarks/pmp/pmp.c vendored Normal file
View file

@ -0,0 +1,212 @@
// See LICENSE for license details.
// Test of PMP functionality.
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include "util.h"
volatile int trap_expected;
volatile int granule;
#define INLINE inline __attribute__((always_inline))
uintptr_t handle_trap(uintptr_t cause, uintptr_t epc, uintptr_t regs[32])
{
if (cause == CAUSE_ILLEGAL_INSTRUCTION)
exit(0); // no PMP support
if (!trap_expected || cause != CAUSE_LOAD_ACCESS)
exit(1);
trap_expected = 0;
return epc + insn_len(epc);
}
#define SCRATCH RISCV_PGSIZE
uintptr_t scratch[RISCV_PGSIZE / sizeof(uintptr_t)] __attribute__((aligned(RISCV_PGSIZE)));
uintptr_t l1pt[RISCV_PGSIZE / sizeof(uintptr_t)] __attribute__((aligned(RISCV_PGSIZE)));
uintptr_t l2pt[RISCV_PGSIZE / sizeof(uintptr_t)] __attribute__((aligned(RISCV_PGSIZE)));
#if __riscv_xlen == 64
uintptr_t l3pt[RISCV_PGSIZE / sizeof(uintptr_t)] __attribute__((aligned(RISCV_PGSIZE)));
#else
#define l3pt l2pt
#endif
static void init_pt()
{
l1pt[0] = ((uintptr_t)l2pt >> RISCV_PGSHIFT << PTE_PPN_SHIFT) | PTE_V;
l3pt[SCRATCH / RISCV_PGSIZE] = ((uintptr_t)scratch >> RISCV_PGSHIFT << PTE_PPN_SHIFT) | PTE_A | PTE_D | PTE_V | PTE_R | PTE_W;
#if __riscv_xlen == 64
l2pt[0] = ((uintptr_t)l3pt >> RISCV_PGSHIFT << PTE_PPN_SHIFT) | PTE_V;
uintptr_t vm_choice = SATP_MODE_SV39;
#else
uintptr_t vm_choice = SATP_MODE_SV32;
#endif
write_csr(sptbr, ((uintptr_t)l1pt >> RISCV_PGSHIFT) |
(vm_choice * (SATP_MODE & ~(SATP_MODE<<1))));
write_csr(pmpaddr2, -1);
write_csr(pmpcfg0, (PMP_NAPOT | PMP_R) << 16);
}
INLINE uintptr_t va2pa(uintptr_t va)
{
if (va < SCRATCH || va >= SCRATCH + RISCV_PGSIZE)
exit(3);
return va - SCRATCH + (uintptr_t)scratch;
}
typedef struct {
uintptr_t cfg;
uintptr_t a0;
uintptr_t a1;
} pmpcfg_t;
INLINE int pmp_ok(pmpcfg_t p, uintptr_t addr, uintptr_t size)
{
if ((p.cfg & PMP_A) == 0)
return 1;
if ((p.cfg & PMP_A) != PMP_TOR) {
uintptr_t range = 1;
if ((p.cfg & PMP_A) == PMP_NAPOT) {
range <<= 1;
for (uintptr_t i = 1; i; i <<= 1) {
if ((p.a1 & i) == 0)
break;
p.a1 &= ~i;
range <<= 1;
}
}
p.a0 = p.a1;
p.a1 = p.a0 + range;
}
p.a0 *= granule;
p.a1 *= granule;
addr = va2pa(addr);
uintptr_t hits = 0;
for (uintptr_t i = 0; i < size; i += granule) {
if (p.a0 <= addr + i && addr + i < p.a1)
hits += granule;
}
return hits == 0 || hits >= size;
}
INLINE void test_one(uintptr_t addr, uintptr_t size)
{
uintptr_t new_mstatus = (read_csr(mstatus) & ~MSTATUS_MPP) | (MSTATUS_MPP & (MSTATUS_MPP >> 1)) | MSTATUS_MPRV;
switch (size) {
case 1: asm volatile ("csrrw %0, mstatus, %0; lb x0, (%1); csrw mstatus, %0" : "+&r" (new_mstatus) : "r" (addr)); break;
case 2: asm volatile ("csrrw %0, mstatus, %0; lh x0, (%1); csrw mstatus, %0" : "+&r" (new_mstatus) : "r" (addr)); break;
case 4: asm volatile ("csrrw %0, mstatus, %0; lw x0, (%1); csrw mstatus, %0" : "+&r" (new_mstatus) : "r" (addr)); break;
#if __riscv_xlen >= 64
case 8: asm volatile ("csrrw %0, mstatus, %0; ld x0, (%1); csrw mstatus, %0" : "+&r" (new_mstatus) : "r" (addr)); break;
#endif
default: __builtin_unreachable();
}
}
INLINE void test_all_sizes(pmpcfg_t p, uintptr_t addr)
{
for (size_t size = 1; size <= sizeof(uintptr_t); size *= 2) {
if (addr & (size - 1))
continue;
trap_expected = !pmp_ok(p, addr, size);
test_one(addr, size);
if (trap_expected)
exit(2);
}
}
INLINE void test_range_once(pmpcfg_t p, uintptr_t base, uintptr_t range)
{
for (uintptr_t addr = base; addr < base + range; addr += granule)
test_all_sizes(p, addr);
}
INLINE pmpcfg_t set_pmp(pmpcfg_t p)
{
uintptr_t cfg0 = read_csr(pmpcfg0);
write_csr(pmpcfg0, cfg0 & ~0xff00);
write_csr(pmpaddr0, p.a0);
write_csr(pmpaddr1, p.a1);
write_csr(pmpcfg0, ((p.cfg << 8) & 0xff00) | (cfg0 & ~0xff00));
asm volatile ("sfence.vma" ::: "memory");
return p;
}
INLINE pmpcfg_t set_pmp_range(uintptr_t base, uintptr_t range)
{
pmpcfg_t p;
p.cfg = PMP_TOR | PMP_R;
p.a0 = base >> PMP_SHIFT;
p.a1 = (base + range) >> PMP_SHIFT;
return set_pmp(p);
}
INLINE pmpcfg_t set_pmp_napot(uintptr_t base, uintptr_t range)
{
pmpcfg_t p;
p.cfg = PMP_R | (range > granule ? PMP_NAPOT : PMP_NA4);
p.a0 = 0;
p.a1 = (base + (range/2 - 1)) >> PMP_SHIFT;
return set_pmp(p);
}
static void test_range(uintptr_t addr, uintptr_t range)
{
pmpcfg_t p = set_pmp_range(va2pa(addr), range);
test_range_once(p, addr, range);
if ((range & (range - 1)) == 0 && (addr & (range - 1)) == 0) {
p = set_pmp_napot(va2pa(addr), range);
test_range_once(p, addr, range);
}
}
static void test_ranges(uintptr_t addr, uintptr_t size)
{
for (uintptr_t range = granule; range <= size; range += granule)
test_range(addr, range);
}
static void exhaustive_test(uintptr_t addr, uintptr_t size)
{
for (uintptr_t base = addr; base < addr + size; base += granule)
test_ranges(base, size - (base - addr));
}
static void detect_granule()
{
write_csr(pmpcfg0, NULL);
write_csr(pmpaddr0, 0xffffffffffffffffULL);
uintptr_t ret = read_csr(pmpaddr0);
int g = 2;
for(uintptr_t i = 1; i; i<<=1) {
if((ret & i) != 0)
break;
g++;
}
granule = 1UL << g;
}
int main()
{
detect_granule();
init_pt();
const int max_exhaustive = 32;
exhaustive_test(SCRATCH, max_exhaustive);
exhaustive_test(SCRATCH + RISCV_PGSIZE - max_exhaustive, max_exhaustive);
test_range(SCRATCH, RISCV_PGSIZE);
test_range(SCRATCH, RISCV_PGSIZE / 2);
test_range(SCRATCH + RISCV_PGSIZE / 2, RISCV_PGSIZE / 2);
return 0;
}

View file

@ -0,0 +1,219 @@
// See LICENSE for license details.
#define DATA_SIZE 2048
type input_data[DATA_SIZE] =
{
89400484, 976015092, 1792756324, 721524505, 1214379246, 3794415, 402845420, 2126940990, 1611680320, 786566648, 754215794, 1231249235, 284658041, 137796456, 2041942843, 329767814, 1255524953, 465119445, 1731949250, 301663421,
1335861008, 452888789, 14125900, 1231149357, 2002881120, 730845665, 1913581092, 1275331596, 843738737, 1931282005, 1492488573, 490920543, 2066865713, 25885333, 238278880, 1898582764, 250731366, 1612593993, 637659983, 1388759892,
916073297, 1075762632, 675549432, 937987129, 1417415680, 1508705426, 1663890071, 1746476698, 686797873, 2109530615, 1459500136, 324215873, 1881253854, 1496277718, 810387144, 1212974417, 1020037994, 585169793, 2017191527, 556328195,
1160036198, 1391095995, 1223583276, 1094283114, 436580096, 190215907, 603159718, 1513255537, 1631935240, 1440145706, 1303736105, 806638567, 1100041120, 1185825535, 1414141069, 2014090929, 419476096, 1273955724, 175753599, 1223475486,
574236644, 2046759770, 492507266, 1721767511, 726141970, 1256152080, 2029909894, 1382429941, 1939683211, 791188057, 519699747, 1051184301, 1962689485, 706913763, 1776471922, 672906535, 2005817027, 1274190723, 2119425672, 835063788,
421198539, 1169327477, 2064145552, 1396662140, 1218522465, 2105638337, 754247044, 2143968639, 1395289708, 1750443194, 1412540552, 170281493, 389233190, 448284065, 240618723, 2145930822, 1846605728, 1353999206, 140536987, 1821559709,
619972089, 1514278798, 750919339, 2143343312, 304427548, 545066288, 1946004194, 1538069400, 1904770864, 924541465, 567779677, 893302687, 1239665569, 1157666831, 2105814934, 1505475223, 1636203720, 9736243, 518073650, 1063743848,
1029176122, 215018112, 1073871430, 1858933377, 866478506, 1491477359, 477407584, 895562064, 954441852, 638167485, 1550159640, 614612685, 1453397990, 1334857284, 683536723, 168771888, 481561285, 755798022, 2016161810, 1162679490,
619428858, 1390306889, 256860662, 365275089, 1322281086, 1134185180, 1302724177, 621921213, 837554186, 1711761015, 754896618, 1723143470, 978247260, 1548804416, 598016845, 1631405417, 790929190, 1602517354, 770957259, 198186681,
1256015513, 2126029304, 135012885, 583112200, 2118203528, 1834388383, 866964848, 1695191950, 745183293, 1143511498, 1112731797, 478721193, 1202162389, 991159735, 1952364329, 519344323, 1667102296, 770412991, 548632788, 714042223,
1674045273, 1471598258, 1286989824, 1590771096, 308832070, 959354209, 72802865, 670621648, 269167950, 1598436917, 2023498746, 1198213061, 2006856683, 1029832956, 1719009954, 1198254803, 1188748563, 1989240516, 927524181, 1711765426,
1394929399, 769005536, 2047006719, 1915435344, 618681206, 1431814151, 42021322, 1106678970, 107160610, 1199317660, 185592115, 1870214195, 205008108, 1834318089, 948686793, 946311527, 1262399341, 131405125, 1321897861, 1459138745,
821481684, 852388468, 603907009, 20643769, 1737931879, 37141933, 2088576982, 366700722, 1761289401, 625991894, 741078359, 817417567, 969305448, 1152416171, 1101933540, 399456957, 2074896270, 1971484382, 747592875, 1160333307,
1738353358, 2113434968, 1896952705, 1908093581, 1155544307, 117766047, 2034767768, 1316120929, 1507433029, 2045407567, 765386206, 1031625002, 1220915309, 325667019, 1916602098, 16411608, 47463938, 1379995885, 1221108420, 721046824,
1431492783, 1569479928, 909415369, 204514903, 933673987, 1565700239, 341674967, 602907378, 5309142, 849489374, 180599971, 1480437960, 532467027, 1958396887, 106223060, 1025117441, 935689637, 1752088215, 1704561346, 1568395337,
1868289345, 569949159, 1045658065, 274746405, 890461390, 507848158, 793505636, 460893030, 1179525294, 388855203, 1113693824, 13887419, 1909681194, 1082499152, 1466632447, 1281443423, 612289854, 373305330, 568652142, 1383640563,
1073695485, 745777837, 624939139, 1289308008, 1928550562, 148113917, 462743614, 1826880531, 1571598133, 1415390230, 1480273562, 1331593955, 540006359, 261556590, 1690167792, 283430575, 1194709162, 1781233744, 649754857, 1434046375,
1135793759, 932423857, 1170759710, 1048943084, 692845661, 1620562432, 2036750157, 270410557, 617995659, 1347284277, 1771614266, 30992839, 655445946, 22762734, 1695617313, 867628573, 1577034674, 227870124, 2063408339, 1512163910,
787913688, 1758748737, 1553547892, 2072440819, 632611704, 873623623, 2097057488, 1879635915, 1404727477, 1840896199, 1609955669, 186112992, 196401930, 130001148, 814302898, 1420810050, 226906236, 1435859758, 221330186, 329049266,
820933470, 260792255, 1401058771, 210908782, 1774652096, 886978116, 1807085904, 508041515, 767233910, 26687179, 318750634, 910677024, 117260224, 2074840378, 301350822, 464795711, 2053899162, 1335298265, 737518341, 777433215,
1147341731, 1981481446, 1628389501, 1537459540, 1121432739, 1392162662, 1800522575, 644293952, 1273223611, 1906345724, 28256901, 1467376771, 372465453, 78348530, 135678410, 1061864942, 260267972, 1184561748, 287497702, 1154842325,
1629914848, 2084953915, 799717076, 1382484003, 2045821218, 933603111, 84924801, 892939912, 279252402, 651750790, 238566180, 942977997, 1822612008, 1849675857, 939497524, 436630343, 549253917, 1028937430, 579174666, 2124749673,
880456526, 1451442832, 1350653461, 1546104436, 858045289, 2129513521, 1181191604, 727587915, 1619598456, 969076419, 1212628403, 1361078114, 368541415, 333906659, 41714278, 1390274260, 1563717683, 973769771, 1078197595, 918378387,
1672192305, 1094531762, 92620223, 2125958841, 1620803320, 915948205, 174965839, 27377406, 435236973, 1038830638, 1834161399, 305750851, 330474090, 730422541, 1634445325, 840106059, 767880329, 109526756, 2027814180, 367923081,
1983379601, 1293091635, 705851791, 226723092, 1067775613, 2082760612, 951663731, 260670135, 1111213862, 1891630185, 1379259015, 176024101, 594814862, 1870859970, 1689946986, 1290969161, 244975305, 1296857499, 1811088032, 1873900475,
1949896838, 1907793490, 592006699, 1312471120, 509744705, 869853078, 70894786, 503368137, 1686479103, 1602967659, 1214950832, 1131661227, 768185796, 592234826, 1727583308, 949222447, 1760851607, 487888229, 1614780688, 1618378831,
602368560, 2028116487, 183679578, 1561251584, 986240059, 1525451290, 977907387, 432609664, 1528031307, 116766659, 987761406, 1630293700, 90063199, 114202152, 543952312, 855107605, 812328969, 88823122, 1092881031, 304131252,
1505022272, 894769708, 1849495275, 1607515830, 1032748996, 472872107, 1593359038, 1027760887, 1074205225, 1657001479, 1524491858, 387061281, 107095939, 1038018856, 798445606, 1486594282, 1878434988, 1558695709, 2033003588, 373226849,
2133066804, 399991238, 1132597050, 1965358941, 1551661799, 3522194, 935939763, 2070467093, 500734709, 533101409, 1068798385, 998931662, 1500102591, 779093898, 66579049, 1121960111, 749415493, 502323961, 538932155, 259768753,
753296935, 87897457, 539429964, 1675300017, 1232992084, 420106224, 1685350721, 346598567, 1610244183, 1597506096, 1079859867, 944382193, 1770497338, 764935753, 1776794410, 866854601, 365854486, 304211060, 344860208, 1361012693,
1450892344, 622170346, 70003859, 1681866717, 435288306, 687941098, 308700094, 1367731096, 1834285819, 255226842, 193873940, 1833603743, 848402819, 152273285, 231181585, 1754447491, 1838218199, 834410115, 229905664, 2052321529,
338532526, 77482422, 12937811, 35859252, 1645969422, 1501181424, 438711458, 1496078411, 419109342, 1455756978, 1234944834, 1287171290, 470090505, 1900162831, 1130850177, 1772760484, 381571915, 1605369007, 514914429, 994291574,
1502557594, 1099847920, 1627355806, 1148699143, 1519017268, 946489895, 106595511, 921573402, 181567810, 1575380740, 1719573683, 1561730727, 1920182565, 1510133268, 1102603775, 1175885101, 802730854, 185979744, 1058937717, 1716853034,
31596852, 462857778, 1335652095, 47036070, 178901145, 1399673078, 222529745, 128036841, 1708126014, 923768127, 1980923963, 1413860940, 1382551511, 208160226, 1892370478, 2091626028, 1793190956, 1417601340, 515811664, 2076612603,
993525189, 1127173529, 245334962, 134453363, 1206302514, 1344125357, 1139159604, 651536866, 22136821, 1536213818, 2143324534, 879878312, 1944679691, 119285206, 832081018, 1566878909, 876130333, 656954306, 226726100, 937976428,
1202009920, 1938258683, 2014129292, 1274436639, 1102423908, 1485740112, 879552408, 1712269139, 650513248, 1068587688, 434850545, 382422699, 919736727, 2022291557, 1319798607, 2139976479, 772059719, 1033910502, 1120963974, 340231765,
1471131758, 1767380006, 47452797, 1313871880, 399114073, 1462921857, 671848647, 31574181, 230340298, 239990424, 590690783, 1714295540, 833019845, 398244682, 522160389, 900852, 1045627895, 1545555937, 226986415, 208433088,
1502480836, 1611500622, 1933923245, 1588715179, 1655277291, 1749972876, 1386258142, 935490932, 173822937, 702380578, 348131466, 81402251, 875481479, 72939206, 2033828953, 1302272656, 64795664, 2010549018, 1652108025, 58217952,
1871684562, 190536346, 244709448, 949010757, 320137025, 729474445, 133790520, 740536012, 316479300, 1191513656, 1802197319, 785398708, 1816641611, 2052328978, 930367387, 1374125186, 303845878, 852835634, 454359988, 2131761201,
1757028186, 536063430, 1765354961, 726869128, 1209784819, 1790557628, 783427298, 2094085507, 1323798820, 846127236, 1065481253, 572240371, 1745543275, 1011417836, 1970797151, 748527394, 343119399, 723323690, 925975225, 901789102,
1726987516, 535828217, 387611445, 464171383, 1170510314, 1166227930, 1807172811, 1942089394, 985305323, 1368235387, 1691486500, 1568900638, 1876255297, 1249183285, 1710305778, 1763785295, 1733366374, 1444076976, 1629633514, 2105321510,
225091211, 898893218, 863551327, 1441811554, 546340809, 1977865396, 2116495484, 1221726287, 293109484, 1601617797, 1568176414, 1424797596, 1256372950, 298799048, 1708002892, 829450571, 891710357, 1994402695, 1136264020, 372280769,
1520667645, 983043723, 1191079043, 680172541, 813511681, 395360213, 1648575360, 1026342885, 2100497812, 422047044, 509116230, 859612092, 2037182006, 895080280, 494367164, 1732028080, 355614494, 2141591317, 1087251698, 580692625,
225934851, 1581062145, 1515262458, 1497680539, 1711718534, 1774796872, 301673313, 1136356724, 653050943, 109035776, 1709823304, 1340949553, 1365423458, 1155459206, 1203897636, 188016786, 256210446, 633075975, 19227407, 1864952910,
1143853106, 237020443, 1750197960, 856837002, 80321564, 1679324299, 1257507406, 1390040163, 1590461855, 806384435, 1331383316, 2027828650, 1649392096, 1928309762, 1027758817, 1267173039, 123889599, 95752736, 2060969286, 619461174,
1686215900, 1817156134, 2118821565, 1596821127, 1800186189, 212821393, 661318748, 1123331233, 146002907, 953877041, 1771924274, 929351822, 2142357746, 356638683, 1610539590, 2001056977, 368889391, 62209567, 1775608361, 992410365,
1336108161, 696448050, 333820982, 585804640, 1775805177, 809604334, 93191015, 732444124, 1492071476, 1930662128, 174082258, 340442582, 507936866, 362748128, 1607204293, 953383750, 1599876594, 416457166, 571635069, 1356847855,
267174620, 2011827638, 1572212863, 589049769, 2024853642, 1680251429, 914906004, 398911194, 795915364, 1332467446, 688483428, 628445699, 578787063, 2006320950, 1167207852, 336213879, 1640952769, 1778544166, 1617229086, 190807078,
1968608155, 2122852959, 31153367, 1353144470, 2196420, 1395155215, 1948121717, 69118708, 2140091269, 2530146, 1740778973, 1601247294, 1205895814, 858150908, 1878253960, 1967705762, 2090543533, 1702425249, 622114437, 1192155877,
1095403694, 2115445751, 1201124879, 1140728569, 2085323316, 1291025252, 871908043, 863647665, 1245819051, 1468486929, 631022494, 1161580432, 539942311, 1943137808, 1826628136, 259775677, 277497333, 2140756121, 973493986, 1121800211,
1539560507, 1337406065, 186178768, 482917205, 1459100749, 1924603748, 390743779, 1140008063, 517767440, 1764436465, 722260205, 1400929335, 1706528514, 486165509, 1379460673, 206653795, 3159407, 565150174, 688338919, 1223572435,
2122262571, 513009937, 1390656632, 271906847, 1622692876, 1313115559, 2061144988, 411864717, 437710825, 513582947, 305489695, 1713188647, 387273799, 1901537567, 644842409, 1231932661, 356672421, 232170581, 1636860706, 302219842,
2094591332, 1697686200, 1390477985, 1833543700, 1203377492, 50968578, 1332379148, 1514582723, 909273561, 1914809801, 560663378, 1032914339, 1216475831, 113462155, 1165446977, 800591831, 1058677375, 432102601, 2131797509, 1175004233,
1602827413, 878884686, 446372159, 257728183, 800661980, 1387864976, 2004770236, 999229412, 1428223489, 175843632, 74887898, 630393584, 1147793249, 112648605, 1028529524, 1891904961, 1953919896, 481563348, 436476038, 1601134240,
72319656, 1581118537, 460420451, 1904576737, 786297537, 359735266, 1918354829, 4031164, 1679777458, 1144017176, 1462192184, 690865719, 1515933932, 363508800, 1480324438, 1044088643, 2036061488, 218671081, 830595166, 381933797,
108346070, 92271196, 217762975, 1522316172, 1021014457, 1407094080, 857894203, 1968623233, 1459620801, 1345014111, 709651138, 520511102, 2048560397, 1768795266, 1013901419, 1709697877, 1026380990, 1377995642, 1560142576, 542609105,
1534330971, 528024121, 2015847175, 325324443, 1137511396, 1883999260, 1871060346, 715940689, 167653495, 1292049996, 1172290275, 2018336444, 1951228823, 1666074170, 1834852613, 854475547, 308857120, 502558280, 2105718728, 1624653209,
514214340, 976063110, 227427283, 912381406, 785989696, 451448729, 212046016, 2068743361, 117280545, 1936668087, 210748671, 1984152603, 945948973, 1409001936, 1644353864, 1139018167, 678475375, 1279061703, 723930558, 195379046,
1498554338, 999346398, 1665914525, 1473735214, 1561422777, 151416112, 697817760, 1622758049, 607761482, 69889880, 1152335090, 1063657548, 1338090388, 55461678, 1278053582, 837024327, 1914764659, 1049475248, 161502390, 80404202,
624714335, 879380479, 1066787659, 1375470750, 1561212123, 59384706, 966363087, 2044016080, 1178086274, 1159745061, 291298358, 173062659, 1385675177, 652078020, 1802327778, 1555660285, 623909040, 1579725218, 1649344003, 270814499,
350182379, 1188076819, 893957771, 534384094, 1057003814, 230634042, 2117880007, 778834747, 250859482, 104637677, 1328272543, 1869264274, 1847908587, 311127477, 506466155, 1808237662, 607471900, 1558244592, 1228817775, 720339756,
1963053072, 1011473945, 1204992245, 566166447, 419053054, 737377568, 520329478, 1740099311, 1682700783, 1455316979, 2118805956, 729509794, 1565610678, 722347551, 739596391, 882282387, 926200942, 999899279, 1318032594, 122124863,
1633512617, 1269707634, 380070610, 1043920511, 665601851, 873976891, 717911282, 2135673182, 761851297, 1604330946, 666624765, 513561613, 1504023310, 1128895624, 99511825, 722919148, 1047336724, 550532376, 1082864732, 289686472,
216557804, 1174587016, 845698678, 1554106660, 577410402, 790256415, 675663963, 2029133999, 161450336, 228960529, 743745539, 1352833750, 2123379476, 852338021, 1291070368, 448708980, 1953450944, 923478775, 827496819, 1126017956,
197964832, 281317274, 1171925835, 764902582, 595717488, 2129930580, 1437147036, 1447469119, 755554593, 2130879949, 1835203128, 1547662666, 1855359256, 965490116, 672323245, 182598318, 216435361, 1324723894, 1144669754, 454438520,
1220523503, 1520886946, 1797641070, 1585050246, 797060176, 1821482472, 2128078174, 973367349, 991874801, 679519053, 1961647235, 2094159153, 391321675, 1604357658, 576906032, 1712341869, 344515114, 1122768484, 1659079595, 1328885292,
48775768, 247448424, 1836119534, 1564061243, 1386366954, 485818381, 37017340, 356546370, 1675494182, 430093707, 1959222232, 1784682542, 1839063567, 1596042792, 295666215, 403378386, 2114587535, 1515528736, 1541546082, 1444048519,
1215103809, 1687941280, 1546057655, 1905279500, 544899032, 2069178089, 1688652157, 1414160501, 332201519, 631936923, 423299667, 1332937015, 545602285, 310273032, 960982228, 372501343, 1933532372, 1711569347, 11476473, 155845605,
700725671, 1457464894, 1325083914, 172109594, 664387510, 1705378439, 376781122, 1472567100, 343682568, 1370528050, 265363198, 2079492652, 1803183394, 519194709, 1538391713, 1931493432, 1183464058, 1489699243, 495097609, 801046035,
177100916, 1292413659, 1348373925, 1550525411, 697685269, 856621012, 1992941115, 1189141368, 221661515, 156760399, 38620214, 375863194, 2078528215, 2103236982, 341987235, 698660475, 381094614, 1201152163, 1275500498, 398211404,
801610475, 1087556673, 846650758, 1848681194, 1287830283, 1400070607, 1603428054, 1233022905, 810516965, 690710531, 1860435620, 750631050, 1271370220, 860360715, 1189323192, 1913926325, 946425090, 1815408878, 743572345, 1902501708,
1276205250, 2005653265, 624614472, 2108439398, 1952177514, 964348374, 1171051384, 2126963607, 812288356, 108628319, 980702956, 714456194, 1678967663, 1935271536, 236851791, 1541132933, 1066014062, 1607628402, 1926717418, 954942098,
1733982669, 14239125, 1506716966, 848141854, 1178260876, 614222093, 731606176, 1512135729, 63244522, 968848252, 1783943137, 1402735006, 1355391150, 1659137391, 1173889730, 1042942541, 1318900244, 1149113346, 2090025563, 1201659316,
250022739, 1035075488, 674580901, 1090386021, 1943651015, 934048997, 2087660971, 738682048, 1305071296, 91177380, 1708106609, 1685880008, 364589031, 1860839427, 1927367009, 906899219, 1090443335, 892574149, 1969729134, 1874026715,
927045887, 1159898528, 730296520, 349249331, 317980803, 225908941, 483348027, 1035956563, 241537930, 1279981214, 1247518755, 247447060, 1793747608, 752388169, 288054543, 2073482870, 2039012903, 617768643, 433412593, 499898207,
1050512245, 331284679, 851322111, 1294873695, 1715379173, 1159675637, 1029338154, 2027445678, 1653332243, 1874855959, 1234157881, 260674360, 1042790263, 1401980800, 730090881, 1745393357, 1550721460, 1607677838, 969500483, 778702716,
1765830270, 731763278, 1600023202, 1957728250, 690983, 444361278, 1278777407, 1231639101, 597427397, 1087245613, 258177907, 2093472294, 1462778368, 2067100479, 1628387880, 762564955, 1194041213, 1348361229, 1822279764, 1826590258,
1112056034, 2088786920, 815110420, 1957877704, 1087195269, 881982271, 1945110368, 1656527154, 529233847, 137046551, 522408049, 1880577483, 847255974, 851716534, 925604268, 1037521069, 461527795, 1332620900, 525605961, 1389787451,
1127911377, 1198857033, 859385989, 706825946, 371790550, 145611377, 655200896, 1900613055, 1333790305, 1101722351, 1278794420, 2089981667, 1150780072, 13180701, 1502266386, 1103013140, 343038558, 1897907456, 1612609979, 1209991461,
1740783613, 1643991754, 977454680, 787842886, 163362230, 1087742330, 200253206, 1691676526, 360632817, 1787338655, 35595330, 822635252, 1834254978, 1372169786, 1063768444, 973490494, 697866347, 156498369, 169293723, 180549009,
112035400, 127867199, 241711645, 2004664325, 23288667, 1997381015, 736455241, 1986921372, 1570645300, 2067499753, 1463269859, 148527979, 618168829, 1715279374, 2066440075, 2118433006, 198233440, 1835860030, 1345873587, 1902595458,
1961619988, 1291438802, 1325008187, 836983022, 1849657867, 500376868, 1599565995, 1705905941, 1600493361, 386733714, 1028820236, 1663100626, 1322696419, 1482983072, 1092382563, 1667679197, 1965855212, 1063839036, 1742032331, 300191208,
620497725, 503895325, 2094864173, 928179911, 277942057, 1677449797, 1249086623, 799527371, 1180063064, 48311975, 1866094167, 1405763119, 2109851473, 1594621666, 580464203, 1752598186, 1339293088, 922186026, 1403771494, 299505702,
1345987999, 1298200648, 2128826472, 677220745, 831273447, 741184696, 696188251, 1912065710, 1016469330, 682018288, 353946286, 559509624, 515414188, 1852181952, 407771887, 812094461, 1859683061, 1100089300, 498702377, 653626077,
765701205, 150878039, 328551896, 77104822, 1775331228, 1835977906, 706357381, 1240287664, 839507573, 1054066034, 1823053058, 701959731, 82879528, 652404808, 866097476, 926939064, 1326017288, 1747861289, 1173840088, 1524006589,
443704960, 835506582, 5363460, 2068343250, 1683915700, 2080735477, 1913489530, 951256529, 1752318678, 105384223, 1788389051, 1787391786, 1430821640, 540952308, 882484999, 690806365, 202502890, 1593837351, 530093821, 385878401,
907401151, 378912543, 454746323, 251514112, 1451277631, 1125822965, 21289266, 1642884452, 804368379, 2048205721, 917508270, 1514792012, 139494505, 1143168018, 115016418, 1730333306, 1630776459, 50748643, 1745247524, 1313640711,
1076198976, 1820281480, 941471466, 806673335, 722162727, 1837280287, 705508794, 2088955494, 510497580, 51692325, 893597382, 1373978529, 1007042224, 685006165, 1471461419, 1555325521, 1215063385, 1424859828, 657251271, 1391827090,
965562483, 604275115, 1285258674, 341475746, 294191106, 633240394, 1897691227, 1904243956, 823532901, 1577955754, 2016464961, 1862876260, 577384103, 1012611702, 247243083, 636485510, 1952805989, 1447876480, 108021700, 1016615447,
2047769687, 943871886, 787537653, 12744598, 853545598, 334037304, 553373537, 1089408490, 497867498, 2038925801, 1434633879, 1290629443, 75922980, 957037315, 2130252471, 477317888, 952824381, 1686570783, 459340678, 751885764,
836307572, 2027909489, 28791588, 322748588, 1335236478, 787106123, 113580144, 954915740, 1317077622, 1299667896, 2009244921, 1548588723, 2049698913, 732388681, 1781891230, 2090684129, 993786972, 1959292396, 1336513734, 691093904,
1746904676, 935573751, 1123555638, 108413311, 1445352642, 169726789, 123352211, 1635952299, 673775121, 2042861943, 757787251, 512494446, 119656942, 58159196, 2090570016, 486181025, 1619641914, 432990571, 894937325, 379470588,
1890938638, 1886317932, 1858637614, 969358207, 1230449468, 1890889527, 351741654, 214725897, 1550012286, 308005013, 26292400, 68067591, 1383307838, 1746273091, 1090104632, 1658037573, 2081544705, 1133473813, 1680294422, 1050373352,
1806061681, 1713475126, 520699193, 417568373, 1355086853, 631399565, 1742434188, 2077667592, 1709019727, 594054971, 937081176, 742185643, 1904514273, 887841601, 1288684086, 424587711, 1497926365, 829844031, 1384314543, 250129297,
200083737, 693737559, 1527022962, 1462501905, 1687540458, 1156824624, 241481265, 1190890142, 1250360726, 2064308502, 27563032, 1880483834, 1984143440, 104727360, 1324123626, 1089710430, 1403206383, 1930880552, 773197243, 1160186023,
562994480, 1065136414, 502237764, 1642338733, 1310177444, 1730721241, 1475638246, 615734453, 1160537912, 928836931, 253898558, 1799210492, 1205522527, 413058646, 1589194592, 1774218355, 43955934, 1673314595, 683393460, 1260859787,
2098829619, 772503535, 1232567659, 758174758, 831270563, 1605294199, 1660678300, 24379565, 1426483935, 1611558740, 1085326591, 12849216, 455856722, 878692218, 1910978116, 1382893830, 1950124297, 950009818, 904287249, 791384486,
1584408128, 210098472, 1110387095, 364620240, 53868166, 772251062, 472745168, 1133910514, 1715402379, 1445225855, 1541125975, 149171217, 972058766, 1893095488, 1487620835, 640835502, 1470285405, 646688705, 988431201, 703130341,
1753125385, 1985895474, 696002734, 1783233173, 1317201705, 1755204784, 532132334, 1069450170, 249700039, 524320231, 757959820, 2109052886, 604977130, 1971654864, 1588222158, 1533496974, 623670976, 1405668251, 1955436051, 1082881617,
1387039848, 874153641, 1345378476, 1168465459, 2005021017, 234039217, 473318229, 654912216, 1473166451, 997649666, 801824335, 2052343947, 1883168929, 185658088, 1389954587, 1725541486, 885873448, 958774566, 2054212564, 60536525,
1427504270, 1160285859, 1827651881, 1408805003, 1684018729, 61716770, 844057079, 1011596733, 1521350211, 1581801257, 907554175, 2022973269, 1125104871, 1312064004, 1466679625, 970194422, 80900939, 1445279202, 335456148, 510478312,
92860378, 1646704157, 1650899832, 1533447203, 268087516, 880688023, 1180525723, 1868151949, 1750955971, 401446720, 540093580, 1022861633, 461442838, 1222554291, 456462271, 94760711, 1231111410, 2145073408, 1932108837, 300618464,
2055783490, 980863365, 1308872551, 1010427073, 1399854717, 1217804021, 934700736, 878744414
};
type verify_data[DATA_SIZE] =
{
690983, 900852, 2196420, 2530146, 3159407, 3522194, 3794415, 4031164, 5309142, 5363460, 9736243, 11476473, 12744598, 12849216, 12937811, 13180701, 13887419, 14125900, 14239125, 16411608,
19227407, 20643769, 21289266, 22136821, 22762734, 23288667, 24379565, 25885333, 26292400, 26687179, 27377406, 27563032, 28256901, 28791588, 30992839, 31153367, 31574181, 31596852, 35595330, 35859252,
37017340, 37141933, 38620214, 41714278, 42021322, 43955934, 47036070, 47452797, 47463938, 48311975, 48775768, 50748643, 50968578, 51692325, 53868166, 55461678, 58159196, 58217952, 59384706, 60536525,
61716770, 62209567, 63244522, 64795664, 66579049, 68067591, 69118708, 69889880, 70003859, 70894786, 72319656, 72802865, 72939206, 74887898, 75922980, 77104822, 77482422, 78348530, 80321564, 80404202,
80900939, 81402251, 82879528, 84924801, 87897457, 88823122, 89400484, 90063199, 91177380, 92271196, 92620223, 92860378, 93191015, 94760711, 95752736, 99511825, 104637677, 104727360, 105384223, 106223060,
106595511, 107095939, 107160610, 108021700, 108346070, 108413311, 108628319, 109035776, 109526756, 112035400, 112648605, 113462155, 113580144, 114202152, 115016418, 116766659, 117260224, 117280545, 117766047, 119285206,
119656942, 122124863, 123352211, 123889599, 127867199, 128036841, 130001148, 131405125, 133790520, 134453363, 135012885, 135678410, 137046551, 137796456, 139494505, 140536987, 145611377, 146002907, 148113917, 148527979,
149171217, 150878039, 151416112, 152273285, 155845605, 156498369, 156760399, 161450336, 161502390, 163362230, 167653495, 168771888, 169293723, 169726789, 170281493, 172109594, 173062659, 173822937, 174082258, 174965839,
175753599, 175843632, 176024101, 177100916, 178901145, 180549009, 180599971, 181567810, 182598318, 183679578, 185592115, 185658088, 185979744, 186112992, 186178768, 188016786, 190215907, 190536346, 190807078, 193873940,
195379046, 196401930, 197964832, 198186681, 198233440, 200083737, 200253206, 202502890, 204514903, 205008108, 206653795, 208160226, 208433088, 210098472, 210748671, 210908782, 212046016, 212821393, 214725897, 215018112,
216435361, 216557804, 217762975, 218671081, 221330186, 221661515, 222529745, 225091211, 225908941, 225934851, 226723092, 226726100, 226906236, 226986415, 227427283, 227870124, 228960529, 229905664, 230340298, 230634042,
231181585, 232170581, 234039217, 236851791, 237020443, 238278880, 238566180, 239990424, 240618723, 241481265, 241537930, 241711645, 244709448, 244975305, 245334962, 247243083, 247447060, 247448424, 249700039, 250022739,
250129297, 250731366, 250859482, 251514112, 253898558, 255226842, 256210446, 256860662, 257728183, 258177907, 259768753, 259775677, 260267972, 260670135, 260674360, 260792255, 261556590, 265363198, 267174620, 268087516,
269167950, 270410557, 270814499, 271906847, 274746405, 277497333, 277942057, 279252402, 281317274, 283430575, 284658041, 287497702, 288054543, 289686472, 291298358, 293109484, 294191106, 295666215, 298799048, 299505702,
300191208, 300618464, 301350822, 301663421, 301673313, 302219842, 303845878, 304131252, 304211060, 304427548, 305489695, 305750851, 308005013, 308700094, 308832070, 308857120, 310273032, 311127477, 316479300, 317980803,
318750634, 320137025, 322748588, 324215873, 325324443, 325667019, 328551896, 329049266, 329767814, 330474090, 331284679, 332201519, 333820982, 333906659, 334037304, 335456148, 336213879, 338532526, 340231765, 340442582,
341475746, 341674967, 341987235, 343038558, 343119399, 343682568, 344515114, 344860208, 346598567, 348131466, 349249331, 350182379, 351741654, 353946286, 355614494, 356546370, 356638683, 356672421, 359735266, 360632817,
362748128, 363508800, 364589031, 364620240, 365275089, 365854486, 366700722, 367923081, 368541415, 368889391, 371790550, 372280769, 372465453, 372501343, 373226849, 373305330, 375863194, 376781122, 378912543, 379470588,
380070610, 381094614, 381571915, 381933797, 382422699, 385878401, 386733714, 387061281, 387273799, 387611445, 388855203, 389233190, 390743779, 391321675, 395360213, 398211404, 398244682, 398911194, 399114073, 399456957,
399991238, 401446720, 402845420, 403378386, 407771887, 411864717, 413058646, 416457166, 417568373, 419053054, 419109342, 419476096, 420106224, 421198539, 422047044, 423299667, 424587711, 430093707, 432102601, 432609664,
432990571, 433412593, 434850545, 435236973, 435288306, 436476038, 436580096, 436630343, 437710825, 438711458, 443704960, 444361278, 446372159, 448284065, 448708980, 451448729, 452888789, 454359988, 454438520, 454746323,
455856722, 456462271, 459340678, 460420451, 460893030, 461442838, 461527795, 462743614, 462857778, 464171383, 464795711, 465119445, 470090505, 472745168, 472872107, 473318229, 477317888, 477407584, 478721193, 481561285,
481563348, 482917205, 483348027, 485818381, 486165509, 486181025, 487888229, 490920543, 492507266, 494367164, 495097609, 497867498, 498702377, 499898207, 500376868, 500734709, 502237764, 502323961, 502558280, 503368137,
503895325, 506466155, 507848158, 507936866, 508041515, 509116230, 509744705, 510478312, 510497580, 512494446, 513009937, 513561613, 513582947, 514214340, 514914429, 515414188, 515811664, 517767440, 518073650, 519194709,
519344323, 519699747, 520329478, 520511102, 520699193, 522160389, 522408049, 524320231, 525605961, 528024121, 529233847, 530093821, 532132334, 532467027, 533101409, 534384094, 535828217, 536063430, 538932155, 539429964,
539942311, 540006359, 540093580, 540952308, 542609105, 543952312, 544899032, 545066288, 545602285, 546340809, 548632788, 549253917, 550532376, 553373537, 556328195, 559509624, 560663378, 562994480, 565150174, 566166447,
567779677, 568652142, 569949159, 571635069, 572240371, 574236644, 576906032, 577384103, 577410402, 578787063, 579174666, 580464203, 580692625, 583112200, 585169793, 585804640, 589049769, 590690783, 592006699, 592234826,
594054971, 594814862, 595717488, 597427397, 598016845, 602368560, 602907378, 603159718, 603907009, 604275115, 604977130, 607471900, 607761482, 612289854, 614222093, 614612685, 615734453, 617768643, 617995659, 618168829,
618681206, 619428858, 619461174, 619972089, 620497725, 621921213, 622114437, 622170346, 623670976, 623909040, 624614472, 624714335, 624939139, 625991894, 628445699, 630393584, 631022494, 631399565, 631936923, 632611704,
633075975, 633240394, 636485510, 637659983, 638167485, 640835502, 644293952, 644842409, 646688705, 649754857, 650513248, 651536866, 651750790, 652078020, 652404808, 653050943, 653626077, 654912216, 655200896, 655445946,
656954306, 657251271, 661318748, 664387510, 665601851, 666624765, 670621648, 671848647, 672323245, 672906535, 673775121, 674580901, 675549432, 675663963, 677220745, 678475375, 679519053, 680172541, 682018288, 683393460,
683536723, 685006165, 686797873, 687941098, 688338919, 688483428, 690710531, 690806365, 690865719, 691093904, 692845661, 693737559, 696002734, 696188251, 696448050, 697685269, 697817760, 697866347, 698660475, 700725671,
701959731, 702380578, 703130341, 705508794, 705851791, 706357381, 706825946, 706913763, 709651138, 714042223, 714456194, 715940689, 717911282, 720339756, 721046824, 721524505, 722162727, 722260205, 722347551, 722919148,
723323690, 723930558, 726141970, 726869128, 727587915, 729474445, 729509794, 730090881, 730296520, 730422541, 730845665, 731606176, 731763278, 732388681, 732444124, 736455241, 737377568, 737518341, 738682048, 739596391,
740536012, 741078359, 741184696, 742185643, 743572345, 743745539, 745183293, 745777837, 747592875, 748527394, 749415493, 750631050, 750919339, 751885764, 752388169, 753296935, 754215794, 754247044, 754896618, 755554593,
755798022, 757787251, 757959820, 758174758, 761851297, 762564955, 764902582, 764935753, 765386206, 765701205, 767233910, 767880329, 768185796, 769005536, 770412991, 770957259, 772059719, 772251062, 772503535, 773197243,
777433215, 778702716, 778834747, 779093898, 783427298, 785398708, 785989696, 786297537, 786566648, 787106123, 787537653, 787842886, 787913688, 790256415, 790929190, 791188057, 791384486, 793505636, 795915364, 797060176,
798445606, 799527371, 799717076, 800591831, 800661980, 801046035, 801610475, 801824335, 802730854, 804368379, 806384435, 806638567, 806673335, 809604334, 810387144, 810516965, 812094461, 812288356, 812328969, 813511681,
814302898, 815110420, 817417567, 820933470, 821481684, 822635252, 823532901, 827496819, 829450571, 829844031, 830595166, 831270563, 831273447, 832081018, 833019845, 834410115, 835063788, 835506582, 836307572, 836983022,
837024327, 837554186, 839507573, 840106059, 843738737, 844057079, 845698678, 846127236, 846650758, 847255974, 848141854, 848402819, 849489374, 851322111, 851716534, 852338021, 852388468, 852835634, 853545598, 854475547,
855107605, 856621012, 856837002, 857894203, 858045289, 858150908, 859385989, 859612092, 860360715, 863551327, 863647665, 866097476, 866478506, 866854601, 866964848, 867628573, 869853078, 871908043, 873623623, 873976891,
874153641, 875481479, 876130333, 878692218, 878744414, 878884686, 879380479, 879552408, 879878312, 880456526, 880688023, 881982271, 882282387, 882484999, 885873448, 886978116, 887841601, 890461390, 891710357, 892574149,
892939912, 893302687, 893597382, 893957771, 894769708, 894937325, 895080280, 895562064, 898893218, 901789102, 904287249, 906899219, 907401151, 907554175, 909273561, 909415369, 910677024, 912381406, 914906004, 915948205,
916073297, 917508270, 918378387, 919736727, 921573402, 922186026, 923478775, 923768127, 924541465, 925604268, 925975225, 926200942, 926939064, 927045887, 927524181, 928179911, 928836931, 929351822, 930367387, 932423857,
933603111, 933673987, 934048997, 934700736, 935490932, 935573751, 935689637, 935939763, 937081176, 937976428, 937987129, 939497524, 941471466, 942977997, 943871886, 944382193, 945948973, 946311527, 946425090, 946489895,
948686793, 949010757, 949222447, 950009818, 951256529, 951663731, 952824381, 953383750, 953877041, 954441852, 954915740, 954942098, 957037315, 958774566, 959354209, 960982228, 964348374, 965490116, 965562483, 966363087,
968848252, 969076419, 969305448, 969358207, 969500483, 970194422, 972058766, 973367349, 973490494, 973493986, 973769771, 976015092, 976063110, 977454680, 977907387, 978247260, 980702956, 980863365, 983043723, 985305323,
986240059, 987761406, 988431201, 991159735, 991874801, 992410365, 993525189, 993786972, 994291574, 997649666, 998931662, 999229412, 999346398, 999899279, 1007042224, 1010427073, 1011417836, 1011473945, 1011596733, 1012611702,
1013901419, 1016469330, 1016615447, 1020037994, 1021014457, 1022861633, 1025117441, 1026342885, 1026380990, 1027758817, 1027760887, 1028529524, 1028820236, 1028937430, 1029176122, 1029338154, 1029832956, 1031625002, 1032748996, 1032914339,
1033910502, 1035075488, 1035956563, 1037521069, 1038018856, 1038830638, 1042790263, 1042942541, 1043920511, 1044088643, 1045627895, 1045658065, 1047336724, 1048943084, 1049475248, 1050373352, 1050512245, 1051184301, 1054066034, 1057003814,
1058677375, 1058937717, 1061864942, 1063657548, 1063743848, 1063768444, 1063839036, 1065136414, 1065481253, 1066014062, 1066787659, 1067775613, 1068587688, 1068798385, 1069450170, 1073695485, 1073871430, 1074205225, 1075762632, 1076198976,
1078197595, 1079859867, 1082499152, 1082864732, 1082881617, 1085326591, 1087195269, 1087245613, 1087251698, 1087556673, 1087742330, 1089408490, 1089710430, 1090104632, 1090386021, 1090443335, 1092382563, 1092881031, 1094283114, 1094531762,
1095403694, 1099847920, 1100041120, 1100089300, 1101722351, 1101933540, 1102423908, 1102603775, 1103013140, 1106678970, 1110387095, 1111213862, 1112056034, 1112731797, 1113693824, 1120963974, 1121432739, 1121800211, 1121960111, 1122768484,
1123331233, 1123555638, 1125104871, 1125822965, 1126017956, 1127173529, 1127911377, 1128895624, 1130850177, 1131661227, 1132597050, 1133473813, 1133910514, 1134185180, 1135793759, 1136264020, 1136356724, 1137511396, 1139018167, 1139159604,
1140008063, 1140728569, 1143168018, 1143511498, 1143853106, 1144017176, 1144669754, 1147341731, 1147793249, 1148699143, 1149113346, 1150780072, 1152335090, 1152416171, 1154842325, 1155459206, 1155544307, 1156824624, 1157666831, 1159675637,
1159745061, 1159898528, 1160036198, 1160186023, 1160285859, 1160333307, 1160537912, 1161580432, 1162679490, 1165446977, 1166227930, 1167207852, 1168465459, 1169327477, 1170510314, 1170759710, 1171051384, 1171925835, 1172290275, 1173840088,
1173889730, 1174587016, 1175004233, 1175885101, 1178086274, 1178260876, 1179525294, 1180063064, 1180525723, 1181191604, 1183464058, 1184561748, 1185825535, 1188076819, 1188748563, 1189141368, 1189323192, 1190890142, 1191079043, 1191513656,
1192155877, 1194041213, 1194709162, 1198213061, 1198254803, 1198857033, 1199317660, 1201124879, 1201152163, 1201659316, 1202009920, 1202162389, 1203377492, 1203897636, 1204992245, 1205522527, 1205895814, 1206302514, 1209784819, 1209991461,
1212628403, 1212974417, 1214379246, 1214950832, 1215063385, 1215103809, 1216475831, 1217804021, 1218522465, 1220523503, 1220915309, 1221108420, 1221726287, 1222554291, 1223475486, 1223572435, 1223583276, 1228817775, 1230449468, 1231111410,
1231149357, 1231249235, 1231639101, 1231932661, 1232567659, 1232992084, 1233022905, 1234157881, 1234944834, 1239665569, 1240287664, 1245819051, 1247518755, 1249086623, 1249183285, 1250360726, 1255524953, 1256015513, 1256152080, 1256372950,
1257507406, 1260859787, 1262399341, 1267173039, 1269707634, 1271370220, 1273223611, 1273955724, 1274190723, 1274436639, 1275331596, 1275500498, 1276205250, 1278053582, 1278777407, 1278794420, 1279061703, 1279981214, 1281443423, 1285258674,
1286989824, 1287171290, 1287830283, 1288684086, 1289308008, 1290629443, 1290969161, 1291025252, 1291070368, 1291438802, 1292049996, 1292413659, 1293091635, 1294873695, 1296857499, 1298200648, 1299667896, 1302272656, 1302724177, 1303736105,
1305071296, 1308872551, 1310177444, 1312064004, 1312471120, 1313115559, 1313640711, 1313871880, 1316120929, 1317077622, 1317201705, 1318032594, 1318900244, 1319798607, 1321897861, 1322281086, 1322696419, 1323798820, 1324123626, 1324723894,
1325008187, 1325083914, 1326017288, 1328272543, 1328885292, 1331383316, 1331593955, 1332379148, 1332467446, 1332620900, 1332937015, 1333790305, 1334857284, 1335236478, 1335298265, 1335652095, 1335861008, 1336108161, 1336513734, 1337406065,
1338090388, 1339293088, 1340949553, 1344125357, 1345014111, 1345378476, 1345873587, 1345987999, 1347284277, 1348361229, 1348373925, 1350653461, 1352833750, 1353144470, 1353999206, 1355086853, 1355391150, 1356847855, 1361012693, 1361078114,
1365423458, 1367731096, 1368235387, 1370528050, 1372169786, 1373978529, 1374125186, 1375470750, 1377995642, 1379259015, 1379460673, 1379995885, 1382429941, 1382484003, 1382551511, 1382893830, 1383307838, 1383640563, 1384314543, 1385675177,
1386258142, 1386366954, 1387039848, 1387864976, 1388759892, 1389787451, 1389954587, 1390040163, 1390274260, 1390306889, 1390477985, 1390656632, 1391095995, 1391827090, 1392162662, 1394929399, 1395155215, 1395289708, 1396662140, 1399673078,
1399854717, 1400070607, 1400929335, 1401058771, 1401980800, 1402735006, 1403206383, 1403771494, 1404727477, 1405668251, 1405763119, 1407094080, 1408805003, 1409001936, 1412540552, 1413860940, 1414141069, 1414160501, 1415390230, 1417415680,
1417601340, 1420810050, 1424797596, 1424859828, 1426483935, 1427504270, 1428223489, 1430821640, 1431492783, 1431814151, 1434046375, 1434633879, 1435859758, 1437147036, 1440145706, 1441811554, 1444048519, 1444076976, 1445225855, 1445279202,
1445352642, 1447469119, 1447876480, 1450892344, 1451277631, 1451442832, 1453397990, 1455316979, 1455756978, 1457464894, 1459100749, 1459138745, 1459500136, 1459620801, 1462192184, 1462501905, 1462778368, 1462921857, 1463269859, 1466632447,
1466679625, 1467376771, 1468486929, 1470285405, 1471131758, 1471461419, 1471598258, 1472567100, 1473166451, 1473735214, 1475638246, 1480273562, 1480324438, 1480437960, 1482983072, 1485740112, 1486594282, 1487620835, 1489699243, 1491477359,
1492071476, 1492488573, 1496078411, 1496277718, 1497680539, 1497926365, 1498554338, 1500102591, 1501181424, 1502266386, 1502480836, 1502557594, 1504023310, 1505022272, 1505475223, 1506716966, 1507433029, 1508705426, 1510133268, 1512135729,
1512163910, 1513255537, 1514278798, 1514582723, 1514792012, 1515262458, 1515528736, 1515933932, 1519017268, 1520667645, 1520886946, 1521350211, 1522316172, 1524006589, 1524491858, 1525451290, 1527022962, 1528031307, 1533447203, 1533496974,
1534330971, 1536213818, 1537459540, 1538069400, 1538391713, 1539560507, 1541125975, 1541132933, 1541546082, 1545555937, 1546057655, 1546104436, 1547662666, 1548588723, 1548804416, 1550012286, 1550159640, 1550525411, 1550721460, 1551661799,
1553547892, 1554106660, 1555325521, 1555660285, 1558244592, 1558695709, 1560142576, 1561212123, 1561251584, 1561422777, 1561730727, 1563717683, 1564061243, 1565610678, 1565700239, 1566878909, 1568176414, 1568395337, 1568900638, 1569479928,
1570645300, 1571598133, 1572212863, 1575380740, 1577034674, 1577955754, 1579725218, 1581062145, 1581118537, 1581801257, 1584408128, 1585050246, 1588222158, 1588715179, 1589194592, 1590461855, 1590771096, 1593359038, 1593837351, 1594621666,
1596042792, 1596821127, 1597506096, 1598436917, 1599565995, 1599876594, 1600023202, 1600493361, 1601134240, 1601247294, 1601617797, 1602517354, 1602827413, 1602967659, 1603428054, 1604330946, 1604357658, 1605294199, 1605369007, 1607204293,
1607515830, 1607628402, 1607677838, 1609955669, 1610244183, 1610539590, 1611500622, 1611558740, 1611680320, 1612593993, 1612609979, 1614780688, 1617229086, 1618378831, 1619598456, 1619641914, 1620562432, 1620803320, 1622692876, 1622758049,
1624653209, 1627355806, 1628387880, 1628389501, 1629633514, 1629914848, 1630293700, 1630776459, 1631405417, 1631935240, 1633512617, 1634445325, 1635952299, 1636203720, 1636860706, 1640952769, 1642338733, 1642884452, 1643991754, 1644353864,
1645969422, 1646704157, 1648575360, 1649344003, 1649392096, 1650899832, 1652108025, 1653332243, 1655277291, 1656527154, 1657001479, 1658037573, 1659079595, 1659137391, 1660678300, 1663100626, 1663890071, 1665914525, 1666074170, 1667102296,
1667679197, 1672192305, 1673314595, 1674045273, 1675300017, 1675494182, 1677449797, 1678967663, 1679324299, 1679777458, 1680251429, 1680294422, 1681866717, 1682700783, 1683915700, 1684018729, 1685350721, 1685880008, 1686215900, 1686479103,
1686570783, 1687540458, 1687941280, 1688652157, 1689946986, 1690167792, 1691486500, 1691676526, 1695191950, 1695617313, 1697686200, 1702425249, 1704561346, 1705378439, 1705905941, 1706528514, 1708002892, 1708106609, 1708126014, 1709019727,
1709697877, 1709823304, 1710305778, 1711569347, 1711718534, 1711761015, 1711765426, 1712269139, 1712341869, 1713188647, 1713475126, 1714295540, 1715279374, 1715379173, 1715402379, 1716853034, 1719009954, 1719573683, 1721767511, 1723143470,
1725541486, 1726987516, 1727583308, 1730333306, 1730721241, 1731949250, 1732028080, 1733366374, 1733982669, 1737931879, 1738353358, 1740099311, 1740778973, 1740783613, 1742032331, 1742434188, 1745247524, 1745393357, 1745543275, 1746273091,
1746476698, 1746904676, 1747861289, 1749972876, 1750197960, 1750443194, 1750955971, 1752088215, 1752318678, 1752598186, 1753125385, 1754447491, 1755204784, 1757028186, 1758748737, 1760851607, 1761289401, 1763785295, 1764436465, 1765354961,
1765830270, 1767380006, 1768795266, 1770497338, 1771614266, 1771924274, 1772760484, 1774218355, 1774652096, 1774796872, 1775331228, 1775608361, 1775805177, 1776471922, 1776794410, 1778544166, 1781233744, 1781891230, 1783233173, 1783943137,
1784682542, 1787338655, 1787391786, 1788389051, 1790557628, 1792756324, 1793190956, 1793747608, 1797641070, 1799210492, 1800186189, 1800522575, 1802197319, 1802327778, 1803183394, 1806061681, 1807085904, 1807172811, 1808237662, 1811088032,
1815408878, 1816641611, 1817156134, 1820281480, 1821482472, 1821559709, 1822279764, 1822612008, 1823053058, 1826590258, 1826628136, 1826880531, 1827651881, 1833543700, 1833603743, 1834161399, 1834254978, 1834285819, 1834318089, 1834388383,
1834852613, 1835203128, 1835860030, 1835977906, 1836119534, 1837280287, 1838218199, 1839063567, 1840896199, 1846605728, 1847908587, 1848681194, 1849495275, 1849657867, 1849675857, 1852181952, 1855359256, 1858637614, 1858933377, 1859683061,
1860435620, 1860839427, 1862876260, 1864952910, 1866094167, 1868151949, 1868289345, 1869264274, 1870214195, 1870859970, 1871060346, 1871684562, 1873900475, 1874026715, 1874855959, 1876255297, 1878253960, 1878434988, 1879635915, 1880483834,
1880577483, 1881253854, 1883168929, 1883999260, 1886317932, 1890889527, 1890938638, 1891630185, 1891904961, 1892370478, 1893095488, 1896952705, 1897691227, 1897907456, 1898582764, 1900162831, 1900613055, 1901537567, 1902501708, 1902595458,
1904243956, 1904514273, 1904576737, 1904770864, 1905279500, 1906345724, 1907793490, 1908093581, 1909681194, 1910978116, 1912065710, 1913489530, 1913581092, 1913926325, 1914764659, 1914809801, 1915435344, 1916602098, 1918354829, 1920182565,
1924603748, 1926717418, 1927367009, 1928309762, 1928550562, 1930662128, 1930880552, 1931282005, 1931493432, 1932108837, 1933532372, 1933923245, 1935271536, 1936668087, 1938258683, 1939683211, 1942089394, 1943137808, 1943651015, 1944679691,
1945110368, 1946004194, 1948121717, 1949896838, 1950124297, 1951228823, 1952177514, 1952364329, 1952805989, 1953450944, 1953919896, 1955436051, 1957728250, 1957877704, 1958396887, 1959222232, 1959292396, 1961619988, 1961647235, 1962689485,
1963053072, 1965358941, 1965855212, 1967705762, 1968608155, 1968623233, 1969729134, 1970797151, 1971484382, 1971654864, 1977865396, 1980923963, 1981481446, 1983379601, 1984143440, 1984152603, 1985895474, 1986921372, 1989240516, 1992941115,
1994402695, 1997381015, 2001056977, 2002881120, 2004664325, 2004770236, 2005021017, 2005653265, 2005817027, 2006320950, 2006856683, 2009244921, 2010549018, 2011827638, 2014090929, 2014129292, 2015847175, 2016161810, 2016464961, 2017191527,
2018336444, 2022291557, 2022973269, 2023498746, 2024853642, 2027445678, 2027814180, 2027828650, 2027909489, 2028116487, 2029133999, 2029909894, 2033003588, 2033828953, 2034767768, 2036061488, 2036750157, 2037182006, 2038925801, 2039012903,
2041942843, 2042861943, 2044016080, 2045407567, 2045821218, 2046759770, 2047006719, 2047769687, 2048205721, 2048560397, 2049698913, 2052321529, 2052328978, 2052343947, 2053899162, 2054212564, 2055783490, 2060969286, 2061144988, 2063408339,
2064145552, 2064308502, 2066440075, 2066865713, 2067100479, 2067499753, 2068343250, 2068743361, 2069178089, 2070467093, 2072440819, 2073482870, 2074840378, 2074896270, 2076612603, 2077667592, 2078528215, 2079492652, 2080735477, 2081544705,
2082760612, 2084953915, 2085323316, 2087660971, 2088576982, 2088786920, 2088955494, 2089981667, 2090025563, 2090543533, 2090570016, 2090684129, 2091626028, 2093472294, 2094085507, 2094159153, 2094591332, 2094864173, 2097057488, 2098829619,
2100497812, 2103236982, 2105321510, 2105638337, 2105718728, 2105814934, 2108439398, 2109052886, 2109530615, 2109851473, 2113434968, 2114587535, 2115445751, 2116495484, 2117880007, 2118203528, 2118433006, 2118805956, 2118821565, 2119425672,
2122262571, 2122852959, 2123379476, 2124749673, 2125958841, 2126029304, 2126940990, 2126963607, 2128078174, 2128826472, 2129513521, 2129930580, 2130252471, 2130879949, 2131761201, 2131797509, 2133066804, 2135673182, 2139976479, 2140091269,
2140756121, 2141591317, 2142357746, 2143324534, 2143343312, 2143968639, 2145073408, 2145930822
};

View file

@ -0,0 +1,132 @@
#!/usr/bin/perl -w
#==========================================================================
# qsort_gendata.pl
#
# Author : Christopher Batten (cbatten@mit.edu)
# Date : April 29, 2005
#
(our $usageMsg = <<'ENDMSG') =~ s/^\#//gm;
#
# Simple script which creates an input data set and the reference data
# for the qsort benchmark.
#
ENDMSG
use strict "vars";
use warnings;
no warnings("once");
use Getopt::Long;
#--------------------------------------------------------------------------
# Command line processing
#--------------------------------------------------------------------------
our %opts;
sub usage()
{
print "\n";
print " Usage: qsort_gendata.pl [options] \n";
print "\n";
print " Options:\n";
print " --help print this message\n";
print " --size size of input data [250]\n";
print " --seed random seed [1]\n";
print "$usageMsg";
exit();
}
sub processCommandLine()
{
$opts{"help"} = 0;
$opts{"size"} = 250;
$opts{"seed"} = 1;
Getopt::Long::GetOptions( \%opts, 'help|?', 'size:i', 'seed:i' ) or usage();
$opts{"help"} and usage();
}
#--------------------------------------------------------------------------
# Helper Functions
#--------------------------------------------------------------------------
sub printArray
{
my $arrayName = $_[0];
my $arrayRef = $_[1];
my $numCols = 20;
my $arrayLen = scalar(@{$arrayRef});
print "type ".$arrayName."[DATA_SIZE] = \n";
print "{\n";
if ( $arrayLen <= $numCols ) {
print " ";
for ( my $i = 0; $i < $arrayLen; $i++ ) {
print sprintf("%3d",$arrayRef->[$i]);
if ( $i != $arrayLen-1 ) {
print ", ";
}
}
print "\n";
}
else {
my $numRows = int($arrayLen/$numCols);
for ( my $j = 0; $j < $numRows; $j++ ) {
print " ";
for ( my $i = 0; $i < $numCols; $i++ ) {
my $index = $j*$numCols + $i;
print sprintf("%3d",$arrayRef->[$index]);
if ( $index != $arrayLen-1 ) {
print ", ";
}
}
print "\n";
}
if ( $arrayLen > ($numRows*$numCols) ) {
print " ";
for ( my $i = 0; $i < ($arrayLen-($numRows*$numCols)); $i++ ) {
my $index = $numCols*$numRows + $i;
print sprintf("%3d",$arrayRef->[$index]);
if ( $index != $arrayLen-1 ) {
print ", ";
}
}
print "\n";
}
}
print "};\n\n";
}
#--------------------------------------------------------------------------
# Main
#--------------------------------------------------------------------------
sub main()
{
processCommandLine();
srand($opts{"seed"});
my @values;
for ( my $i = 0; $i < $opts{"size"}; $i++ ) {
push( @values, int(rand((1<<31)-1)) );
}
my @sorted = sort { $a <=> $b } @values;
print "\n\#define DATA_SIZE ".$opts{"size"}." \n\n";
printArray( "input_data", \@values );
printArray( "verify_data", \@sorted );
}
main();

View file

@ -0,0 +1,153 @@
// See LICENSE for license details.
//**************************************************************************
// Quicksort benchmark
//--------------------------------------------------------------------------
//
// This benchmark uses quicksort to sort an array of integers. The
// implementation is largely adapted from Numerical Recipes for C. The
// input data (and reference data) should be generated using the
// qsort_gendata.pl perl script and dumped to a file named
// dataset1.h.
#include "util.h"
#include <string.h>
#include <assert.h>
// The INSERTION_THRESHOLD is the size of the subarray when the
// algorithm switches to using an insertion sort instead of
// quick sort.
#define INSERTION_THRESHOLD 10
// NSTACK is the required auxiliary storage.
// It must be at least 2*lg(DATA_SIZE)
#define NSTACK 50
//--------------------------------------------------------------------------
// Input/Reference Data
#define type int
#include "dataset1.h"
// Swap macro for swapping two values.
#define SWAP(a,b) do { typeof(a) temp=(a);(a)=(b);(b)=temp; } while (0)
#define SWAP_IF_GREATER(a, b) do { if ((a) > (b)) SWAP(a, b); } while (0)
//--------------------------------------------------------------------------
// Quicksort function
static void insertion_sort(size_t n, type arr[])
{
type *i, *j;
type value;
for (i = arr+1; i < arr+n; i++)
{
value = *i;
j = i;
while (value < *(j-1))
{
*j = *(j-1);
if (--j == arr)
break;
}
*j = value;
}
}
static void selection_sort(size_t n, type arr[])
{
for (type* i = arr; i < arr+n-1; i++)
for (type* j = i+1; j < arr+n; j++)
SWAP_IF_GREATER(*i, *j);
}
void sort(size_t n, type arr[])
{
type* ir = arr+n;
type* l = arr+1;
type* stack[NSTACK];
type** stackp = stack;
for (;;)
{
// Insertion sort when subarray small enough.
if ( ir-l < INSERTION_THRESHOLD )
{
insertion_sort(ir - l + 1, l - 1);
if ( stackp == stack ) break;
// Pop stack and begin a new round of partitioning.
ir = *stackp--;
l = *stackp--;
}
else
{
// Choose median of left, center, and right elements as
// partitioning element a. Also rearrange so that a[l-1] <= a[l] <= a[ir-].
SWAP(arr[((l-arr) + (ir-arr))/2-1], l[0]);
SWAP_IF_GREATER(l[-1], ir[-1]);
SWAP_IF_GREATER(l[0], ir[-1]);
SWAP_IF_GREATER(l[-1], l[0]);
// Initialize pointers for partitioning.
type* i = l+1;
type* j = ir;
// Partitioning element.
type a = l[0];
for (;;) { // Beginning of innermost loop.
while (*i++ < a); // Scan up to find element > a.
while (*(j-- - 2) > a); // Scan down to find element < a.
if (j < i) break; // Pointers crossed. Partitioning complete.
SWAP(i[-1], j[-1]); // Exchange elements.
} // End of innermost loop.
// Insert partitioning element.
l[0] = j[-1];
j[-1] = a;
stackp += 2;
// Push pointers to larger subarray on stack,
// process smaller subarray immediately.
if ( ir-i+1 >= j-l )
{
stackp[0] = ir;
stackp[-1] = i;
ir = j-1;
}
else
{
stackp[0] = j-1;
stackp[-1] = l;
l = i;
}
}
}
}
//--------------------------------------------------------------------------
// Main
int main( int argc, char* argv[] )
{
#if PREALLOCATE
// If needed we preallocate everything in the caches
sort(DATA_SIZE, verify_data);
if (verify(DATA_SIZE, input_data, input_data))
return 1;
#endif
// Do the sort
setStats(1);
sort( DATA_SIZE, input_data );
setStats(0);
// Check the results
return verify( DATA_SIZE, input_data, verify_data );
}

View file

@ -0,0 +1,46 @@
*************************************************************************
Benchmarks for RISCV Processor
-------------------------------------------------------------------------
The benchmarks make use of the RISCV C compiler toolchain. You will need
to list each benchmark in bmarks variable of Makefile. There are a couple
important points to make about the toolchain.
+ The toolchain sets the stack pointer to memory address 0x20000 so your
main memory _must_ be larger than 0x20000 bytes or else the stack will
get wrapped around and overwrite program data.
+ The stack grows down from 0x20000 and your program is loaded at 0x1000.
If you have a very large program and have lots of very big arrays
declared on the stack your stack could overwrite your program. Be aware.
+ You cannot use standard clib functions (like memcopy or strcat). You
cannot use system calls and thus cannot use printf.
+ You cannot access the simulated command line - ie you cannot use argc
and argv within main.
+ You may have to increase the timeout check in your test harness to
allow longer programs to run (you can do this from the command line
option +max-cycles with the standard test harness)
+ The compiler loads the program at 0x1000. It does not insert exception
setup code. So if you are careful with what C you use it will only
generate code in the riscv lab1 subset. If you use multiplies, shorts,
and chars it could generate mul, lh, and lb instructions. Be aware.
+ You can write assembly in C - you need to do this to write tohost to 1
to indicate when the benchmark is done. Look at the example
benchmarks to see how this is done. You can find more information
about how to write assembly in C here:
http://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html
+ Debugging C compiled code on the RISCV processor is a real pain. It is
hard to associate the assembly with the C code and there is no
debugger. So if you encounter a bug in your processor when running a C
benchmark you can try to debug it, but you might have better luck
adding more assembly tests to your test suite.
+ To avoid having the compiler try and use a global pointer (ie using
register 28 to point to a space where small global variables are
stored) you need to use the -G 0 command line option.

View file

@ -0,0 +1,219 @@
// See LICENSE for license details.
#define DATA_SIZE 2048
type input_data[DATA_SIZE] =
{
89400484, 976015092, 1792756324, 721524505, 1214379246, 3794415, 402845420, 2126940990, 1611680320, 786566648, 754215794, 1231249235, 284658041, 137796456, 2041942843, 329767814, 1255524953, 465119445, 1731949250, 301663421,
1335861008, 452888789, 14125900, 1231149357, 2002881120, 730845665, 1913581092, 1275331596, 843738737, 1931282005, 1492488573, 490920543, 2066865713, 25885333, 238278880, 1898582764, 250731366, 1612593993, 637659983, 1388759892,
916073297, 1075762632, 675549432, 937987129, 1417415680, 1508705426, 1663890071, 1746476698, 686797873, 2109530615, 1459500136, 324215873, 1881253854, 1496277718, 810387144, 1212974417, 1020037994, 585169793, 2017191527, 556328195,
1160036198, 1391095995, 1223583276, 1094283114, 436580096, 190215907, 603159718, 1513255537, 1631935240, 1440145706, 1303736105, 806638567, 1100041120, 1185825535, 1414141069, 2014090929, 419476096, 1273955724, 175753599, 1223475486,
574236644, 2046759770, 492507266, 1721767511, 726141970, 1256152080, 2029909894, 1382429941, 1939683211, 791188057, 519699747, 1051184301, 1962689485, 706913763, 1776471922, 672906535, 2005817027, 1274190723, 2119425672, 835063788,
421198539, 1169327477, 2064145552, 1396662140, 1218522465, 2105638337, 754247044, 2143968639, 1395289708, 1750443194, 1412540552, 170281493, 389233190, 448284065, 240618723, 2145930822, 1846605728, 1353999206, 140536987, 1821559709,
619972089, 1514278798, 750919339, 2143343312, 304427548, 545066288, 1946004194, 1538069400, 1904770864, 924541465, 567779677, 893302687, 1239665569, 1157666831, 2105814934, 1505475223, 1636203720, 9736243, 518073650, 1063743848,
1029176122, 215018112, 1073871430, 1858933377, 866478506, 1491477359, 477407584, 895562064, 954441852, 638167485, 1550159640, 614612685, 1453397990, 1334857284, 683536723, 168771888, 481561285, 755798022, 2016161810, 1162679490,
619428858, 1390306889, 256860662, 365275089, 1322281086, 1134185180, 1302724177, 621921213, 837554186, 1711761015, 754896618, 1723143470, 978247260, 1548804416, 598016845, 1631405417, 790929190, 1602517354, 770957259, 198186681,
1256015513, 2126029304, 135012885, 583112200, 2118203528, 1834388383, 866964848, 1695191950, 745183293, 1143511498, 1112731797, 478721193, 1202162389, 991159735, 1952364329, 519344323, 1667102296, 770412991, 548632788, 714042223,
1674045273, 1471598258, 1286989824, 1590771096, 308832070, 959354209, 72802865, 670621648, 269167950, 1598436917, 2023498746, 1198213061, 2006856683, 1029832956, 1719009954, 1198254803, 1188748563, 1989240516, 927524181, 1711765426,
1394929399, 769005536, 2047006719, 1915435344, 618681206, 1431814151, 42021322, 1106678970, 107160610, 1199317660, 185592115, 1870214195, 205008108, 1834318089, 948686793, 946311527, 1262399341, 131405125, 1321897861, 1459138745,
821481684, 852388468, 603907009, 20643769, 1737931879, 37141933, 2088576982, 366700722, 1761289401, 625991894, 741078359, 817417567, 969305448, 1152416171, 1101933540, 399456957, 2074896270, 1971484382, 747592875, 1160333307,
1738353358, 2113434968, 1896952705, 1908093581, 1155544307, 117766047, 2034767768, 1316120929, 1507433029, 2045407567, 765386206, 1031625002, 1220915309, 325667019, 1916602098, 16411608, 47463938, 1379995885, 1221108420, 721046824,
1431492783, 1569479928, 909415369, 204514903, 933673987, 1565700239, 341674967, 602907378, 5309142, 849489374, 180599971, 1480437960, 532467027, 1958396887, 106223060, 1025117441, 935689637, 1752088215, 1704561346, 1568395337,
1868289345, 569949159, 1045658065, 274746405, 890461390, 507848158, 793505636, 460893030, 1179525294, 388855203, 1113693824, 13887419, 1909681194, 1082499152, 1466632447, 1281443423, 612289854, 373305330, 568652142, 1383640563,
1073695485, 745777837, 624939139, 1289308008, 1928550562, 148113917, 462743614, 1826880531, 1571598133, 1415390230, 1480273562, 1331593955, 540006359, 261556590, 1690167792, 283430575, 1194709162, 1781233744, 649754857, 1434046375,
1135793759, 932423857, 1170759710, 1048943084, 692845661, 1620562432, 2036750157, 270410557, 617995659, 1347284277, 1771614266, 30992839, 655445946, 22762734, 1695617313, 867628573, 1577034674, 227870124, 2063408339, 1512163910,
787913688, 1758748737, 1553547892, 2072440819, 632611704, 873623623, 2097057488, 1879635915, 1404727477, 1840896199, 1609955669, 186112992, 196401930, 130001148, 814302898, 1420810050, 226906236, 1435859758, 221330186, 329049266,
820933470, 260792255, 1401058771, 210908782, 1774652096, 886978116, 1807085904, 508041515, 767233910, 26687179, 318750634, 910677024, 117260224, 2074840378, 301350822, 464795711, 2053899162, 1335298265, 737518341, 777433215,
1147341731, 1981481446, 1628389501, 1537459540, 1121432739, 1392162662, 1800522575, 644293952, 1273223611, 1906345724, 28256901, 1467376771, 372465453, 78348530, 135678410, 1061864942, 260267972, 1184561748, 287497702, 1154842325,
1629914848, 2084953915, 799717076, 1382484003, 2045821218, 933603111, 84924801, 892939912, 279252402, 651750790, 238566180, 942977997, 1822612008, 1849675857, 939497524, 436630343, 549253917, 1028937430, 579174666, 2124749673,
880456526, 1451442832, 1350653461, 1546104436, 858045289, 2129513521, 1181191604, 727587915, 1619598456, 969076419, 1212628403, 1361078114, 368541415, 333906659, 41714278, 1390274260, 1563717683, 973769771, 1078197595, 918378387,
1672192305, 1094531762, 92620223, 2125958841, 1620803320, 915948205, 174965839, 27377406, 435236973, 1038830638, 1834161399, 305750851, 330474090, 730422541, 1634445325, 840106059, 767880329, 109526756, 2027814180, 367923081,
1983379601, 1293091635, 705851791, 226723092, 1067775613, 2082760612, 951663731, 260670135, 1111213862, 1891630185, 1379259015, 176024101, 594814862, 1870859970, 1689946986, 1290969161, 244975305, 1296857499, 1811088032, 1873900475,
1949896838, 1907793490, 592006699, 1312471120, 509744705, 869853078, 70894786, 503368137, 1686479103, 1602967659, 1214950832, 1131661227, 768185796, 592234826, 1727583308, 949222447, 1760851607, 487888229, 1614780688, 1618378831,
602368560, 2028116487, 183679578, 1561251584, 986240059, 1525451290, 977907387, 432609664, 1528031307, 116766659, 987761406, 1630293700, 90063199, 114202152, 543952312, 855107605, 812328969, 88823122, 1092881031, 304131252,
1505022272, 894769708, 1849495275, 1607515830, 1032748996, 472872107, 1593359038, 1027760887, 1074205225, 1657001479, 1524491858, 387061281, 107095939, 1038018856, 798445606, 1486594282, 1878434988, 1558695709, 2033003588, 373226849,
2133066804, 399991238, 1132597050, 1965358941, 1551661799, 3522194, 935939763, 2070467093, 500734709, 533101409, 1068798385, 998931662, 1500102591, 779093898, 66579049, 1121960111, 749415493, 502323961, 538932155, 259768753,
753296935, 87897457, 539429964, 1675300017, 1232992084, 420106224, 1685350721, 346598567, 1610244183, 1597506096, 1079859867, 944382193, 1770497338, 764935753, 1776794410, 866854601, 365854486, 304211060, 344860208, 1361012693,
1450892344, 622170346, 70003859, 1681866717, 435288306, 687941098, 308700094, 1367731096, 1834285819, 255226842, 193873940, 1833603743, 848402819, 152273285, 231181585, 1754447491, 1838218199, 834410115, 229905664, 2052321529,
338532526, 77482422, 12937811, 35859252, 1645969422, 1501181424, 438711458, 1496078411, 419109342, 1455756978, 1234944834, 1287171290, 470090505, 1900162831, 1130850177, 1772760484, 381571915, 1605369007, 514914429, 994291574,
1502557594, 1099847920, 1627355806, 1148699143, 1519017268, 946489895, 106595511, 921573402, 181567810, 1575380740, 1719573683, 1561730727, 1920182565, 1510133268, 1102603775, 1175885101, 802730854, 185979744, 1058937717, 1716853034,
31596852, 462857778, 1335652095, 47036070, 178901145, 1399673078, 222529745, 128036841, 1708126014, 923768127, 1980923963, 1413860940, 1382551511, 208160226, 1892370478, 2091626028, 1793190956, 1417601340, 515811664, 2076612603,
993525189, 1127173529, 245334962, 134453363, 1206302514, 1344125357, 1139159604, 651536866, 22136821, 1536213818, 2143324534, 879878312, 1944679691, 119285206, 832081018, 1566878909, 876130333, 656954306, 226726100, 937976428,
1202009920, 1938258683, 2014129292, 1274436639, 1102423908, 1485740112, 879552408, 1712269139, 650513248, 1068587688, 434850545, 382422699, 919736727, 2022291557, 1319798607, 2139976479, 772059719, 1033910502, 1120963974, 340231765,
1471131758, 1767380006, 47452797, 1313871880, 399114073, 1462921857, 671848647, 31574181, 230340298, 239990424, 590690783, 1714295540, 833019845, 398244682, 522160389, 900852, 1045627895, 1545555937, 226986415, 208433088,
1502480836, 1611500622, 1933923245, 1588715179, 1655277291, 1749972876, 1386258142, 935490932, 173822937, 702380578, 348131466, 81402251, 875481479, 72939206, 2033828953, 1302272656, 64795664, 2010549018, 1652108025, 58217952,
1871684562, 190536346, 244709448, 949010757, 320137025, 729474445, 133790520, 740536012, 316479300, 1191513656, 1802197319, 785398708, 1816641611, 2052328978, 930367387, 1374125186, 303845878, 852835634, 454359988, 2131761201,
1757028186, 536063430, 1765354961, 726869128, 1209784819, 1790557628, 783427298, 2094085507, 1323798820, 846127236, 1065481253, 572240371, 1745543275, 1011417836, 1970797151, 748527394, 343119399, 723323690, 925975225, 901789102,
1726987516, 535828217, 387611445, 464171383, 1170510314, 1166227930, 1807172811, 1942089394, 985305323, 1368235387, 1691486500, 1568900638, 1876255297, 1249183285, 1710305778, 1763785295, 1733366374, 1444076976, 1629633514, 2105321510,
225091211, 898893218, 863551327, 1441811554, 546340809, 1977865396, 2116495484, 1221726287, 293109484, 1601617797, 1568176414, 1424797596, 1256372950, 298799048, 1708002892, 829450571, 891710357, 1994402695, 1136264020, 372280769,
1520667645, 983043723, 1191079043, 680172541, 813511681, 395360213, 1648575360, 1026342885, 2100497812, 422047044, 509116230, 859612092, 2037182006, 895080280, 494367164, 1732028080, 355614494, 2141591317, 1087251698, 580692625,
225934851, 1581062145, 1515262458, 1497680539, 1711718534, 1774796872, 301673313, 1136356724, 653050943, 109035776, 1709823304, 1340949553, 1365423458, 1155459206, 1203897636, 188016786, 256210446, 633075975, 19227407, 1864952910,
1143853106, 237020443, 1750197960, 856837002, 80321564, 1679324299, 1257507406, 1390040163, 1590461855, 806384435, 1331383316, 2027828650, 1649392096, 1928309762, 1027758817, 1267173039, 123889599, 95752736, 2060969286, 619461174,
1686215900, 1817156134, 2118821565, 1596821127, 1800186189, 212821393, 661318748, 1123331233, 146002907, 953877041, 1771924274, 929351822, 2142357746, 356638683, 1610539590, 2001056977, 368889391, 62209567, 1775608361, 992410365,
1336108161, 696448050, 333820982, 585804640, 1775805177, 809604334, 93191015, 732444124, 1492071476, 1930662128, 174082258, 340442582, 507936866, 362748128, 1607204293, 953383750, 1599876594, 416457166, 571635069, 1356847855,
267174620, 2011827638, 1572212863, 589049769, 2024853642, 1680251429, 914906004, 398911194, 795915364, 1332467446, 688483428, 628445699, 578787063, 2006320950, 1167207852, 336213879, 1640952769, 1778544166, 1617229086, 190807078,
1968608155, 2122852959, 31153367, 1353144470, 2196420, 1395155215, 1948121717, 69118708, 2140091269, 2530146, 1740778973, 1601247294, 1205895814, 858150908, 1878253960, 1967705762, 2090543533, 1702425249, 622114437, 1192155877,
1095403694, 2115445751, 1201124879, 1140728569, 2085323316, 1291025252, 871908043, 863647665, 1245819051, 1468486929, 631022494, 1161580432, 539942311, 1943137808, 1826628136, 259775677, 277497333, 2140756121, 973493986, 1121800211,
1539560507, 1337406065, 186178768, 482917205, 1459100749, 1924603748, 390743779, 1140008063, 517767440, 1764436465, 722260205, 1400929335, 1706528514, 486165509, 1379460673, 206653795, 3159407, 565150174, 688338919, 1223572435,
2122262571, 513009937, 1390656632, 271906847, 1622692876, 1313115559, 2061144988, 411864717, 437710825, 513582947, 305489695, 1713188647, 387273799, 1901537567, 644842409, 1231932661, 356672421, 232170581, 1636860706, 302219842,
2094591332, 1697686200, 1390477985, 1833543700, 1203377492, 50968578, 1332379148, 1514582723, 909273561, 1914809801, 560663378, 1032914339, 1216475831, 113462155, 1165446977, 800591831, 1058677375, 432102601, 2131797509, 1175004233,
1602827413, 878884686, 446372159, 257728183, 800661980, 1387864976, 2004770236, 999229412, 1428223489, 175843632, 74887898, 630393584, 1147793249, 112648605, 1028529524, 1891904961, 1953919896, 481563348, 436476038, 1601134240,
72319656, 1581118537, 460420451, 1904576737, 786297537, 359735266, 1918354829, 4031164, 1679777458, 1144017176, 1462192184, 690865719, 1515933932, 363508800, 1480324438, 1044088643, 2036061488, 218671081, 830595166, 381933797,
108346070, 92271196, 217762975, 1522316172, 1021014457, 1407094080, 857894203, 1968623233, 1459620801, 1345014111, 709651138, 520511102, 2048560397, 1768795266, 1013901419, 1709697877, 1026380990, 1377995642, 1560142576, 542609105,
1534330971, 528024121, 2015847175, 325324443, 1137511396, 1883999260, 1871060346, 715940689, 167653495, 1292049996, 1172290275, 2018336444, 1951228823, 1666074170, 1834852613, 854475547, 308857120, 502558280, 2105718728, 1624653209,
514214340, 976063110, 227427283, 912381406, 785989696, 451448729, 212046016, 2068743361, 117280545, 1936668087, 210748671, 1984152603, 945948973, 1409001936, 1644353864, 1139018167, 678475375, 1279061703, 723930558, 195379046,
1498554338, 999346398, 1665914525, 1473735214, 1561422777, 151416112, 697817760, 1622758049, 607761482, 69889880, 1152335090, 1063657548, 1338090388, 55461678, 1278053582, 837024327, 1914764659, 1049475248, 161502390, 80404202,
624714335, 879380479, 1066787659, 1375470750, 1561212123, 59384706, 966363087, 2044016080, 1178086274, 1159745061, 291298358, 173062659, 1385675177, 652078020, 1802327778, 1555660285, 623909040, 1579725218, 1649344003, 270814499,
350182379, 1188076819, 893957771, 534384094, 1057003814, 230634042, 2117880007, 778834747, 250859482, 104637677, 1328272543, 1869264274, 1847908587, 311127477, 506466155, 1808237662, 607471900, 1558244592, 1228817775, 720339756,
1963053072, 1011473945, 1204992245, 566166447, 419053054, 737377568, 520329478, 1740099311, 1682700783, 1455316979, 2118805956, 729509794, 1565610678, 722347551, 739596391, 882282387, 926200942, 999899279, 1318032594, 122124863,
1633512617, 1269707634, 380070610, 1043920511, 665601851, 873976891, 717911282, 2135673182, 761851297, 1604330946, 666624765, 513561613, 1504023310, 1128895624, 99511825, 722919148, 1047336724, 550532376, 1082864732, 289686472,
216557804, 1174587016, 845698678, 1554106660, 577410402, 790256415, 675663963, 2029133999, 161450336, 228960529, 743745539, 1352833750, 2123379476, 852338021, 1291070368, 448708980, 1953450944, 923478775, 827496819, 1126017956,
197964832, 281317274, 1171925835, 764902582, 595717488, 2129930580, 1437147036, 1447469119, 755554593, 2130879949, 1835203128, 1547662666, 1855359256, 965490116, 672323245, 182598318, 216435361, 1324723894, 1144669754, 454438520,
1220523503, 1520886946, 1797641070, 1585050246, 797060176, 1821482472, 2128078174, 973367349, 991874801, 679519053, 1961647235, 2094159153, 391321675, 1604357658, 576906032, 1712341869, 344515114, 1122768484, 1659079595, 1328885292,
48775768, 247448424, 1836119534, 1564061243, 1386366954, 485818381, 37017340, 356546370, 1675494182, 430093707, 1959222232, 1784682542, 1839063567, 1596042792, 295666215, 403378386, 2114587535, 1515528736, 1541546082, 1444048519,
1215103809, 1687941280, 1546057655, 1905279500, 544899032, 2069178089, 1688652157, 1414160501, 332201519, 631936923, 423299667, 1332937015, 545602285, 310273032, 960982228, 372501343, 1933532372, 1711569347, 11476473, 155845605,
700725671, 1457464894, 1325083914, 172109594, 664387510, 1705378439, 376781122, 1472567100, 343682568, 1370528050, 265363198, 2079492652, 1803183394, 519194709, 1538391713, 1931493432, 1183464058, 1489699243, 495097609, 801046035,
177100916, 1292413659, 1348373925, 1550525411, 697685269, 856621012, 1992941115, 1189141368, 221661515, 156760399, 38620214, 375863194, 2078528215, 2103236982, 341987235, 698660475, 381094614, 1201152163, 1275500498, 398211404,
801610475, 1087556673, 846650758, 1848681194, 1287830283, 1400070607, 1603428054, 1233022905, 810516965, 690710531, 1860435620, 750631050, 1271370220, 860360715, 1189323192, 1913926325, 946425090, 1815408878, 743572345, 1902501708,
1276205250, 2005653265, 624614472, 2108439398, 1952177514, 964348374, 1171051384, 2126963607, 812288356, 108628319, 980702956, 714456194, 1678967663, 1935271536, 236851791, 1541132933, 1066014062, 1607628402, 1926717418, 954942098,
1733982669, 14239125, 1506716966, 848141854, 1178260876, 614222093, 731606176, 1512135729, 63244522, 968848252, 1783943137, 1402735006, 1355391150, 1659137391, 1173889730, 1042942541, 1318900244, 1149113346, 2090025563, 1201659316,
250022739, 1035075488, 674580901, 1090386021, 1943651015, 934048997, 2087660971, 738682048, 1305071296, 91177380, 1708106609, 1685880008, 364589031, 1860839427, 1927367009, 906899219, 1090443335, 892574149, 1969729134, 1874026715,
927045887, 1159898528, 730296520, 349249331, 317980803, 225908941, 483348027, 1035956563, 241537930, 1279981214, 1247518755, 247447060, 1793747608, 752388169, 288054543, 2073482870, 2039012903, 617768643, 433412593, 499898207,
1050512245, 331284679, 851322111, 1294873695, 1715379173, 1159675637, 1029338154, 2027445678, 1653332243, 1874855959, 1234157881, 260674360, 1042790263, 1401980800, 730090881, 1745393357, 1550721460, 1607677838, 969500483, 778702716,
1765830270, 731763278, 1600023202, 1957728250, 690983, 444361278, 1278777407, 1231639101, 597427397, 1087245613, 258177907, 2093472294, 1462778368, 2067100479, 1628387880, 762564955, 1194041213, 1348361229, 1822279764, 1826590258,
1112056034, 2088786920, 815110420, 1957877704, 1087195269, 881982271, 1945110368, 1656527154, 529233847, 137046551, 522408049, 1880577483, 847255974, 851716534, 925604268, 1037521069, 461527795, 1332620900, 525605961, 1389787451,
1127911377, 1198857033, 859385989, 706825946, 371790550, 145611377, 655200896, 1900613055, 1333790305, 1101722351, 1278794420, 2089981667, 1150780072, 13180701, 1502266386, 1103013140, 343038558, 1897907456, 1612609979, 1209991461,
1740783613, 1643991754, 977454680, 787842886, 163362230, 1087742330, 200253206, 1691676526, 360632817, 1787338655, 35595330, 822635252, 1834254978, 1372169786, 1063768444, 973490494, 697866347, 156498369, 169293723, 180549009,
112035400, 127867199, 241711645, 2004664325, 23288667, 1997381015, 736455241, 1986921372, 1570645300, 2067499753, 1463269859, 148527979, 618168829, 1715279374, 2066440075, 2118433006, 198233440, 1835860030, 1345873587, 1902595458,
1961619988, 1291438802, 1325008187, 836983022, 1849657867, 500376868, 1599565995, 1705905941, 1600493361, 386733714, 1028820236, 1663100626, 1322696419, 1482983072, 1092382563, 1667679197, 1965855212, 1063839036, 1742032331, 300191208,
620497725, 503895325, 2094864173, 928179911, 277942057, 1677449797, 1249086623, 799527371, 1180063064, 48311975, 1866094167, 1405763119, 2109851473, 1594621666, 580464203, 1752598186, 1339293088, 922186026, 1403771494, 299505702,
1345987999, 1298200648, 2128826472, 677220745, 831273447, 741184696, 696188251, 1912065710, 1016469330, 682018288, 353946286, 559509624, 515414188, 1852181952, 407771887, 812094461, 1859683061, 1100089300, 498702377, 653626077,
765701205, 150878039, 328551896, 77104822, 1775331228, 1835977906, 706357381, 1240287664, 839507573, 1054066034, 1823053058, 701959731, 82879528, 652404808, 866097476, 926939064, 1326017288, 1747861289, 1173840088, 1524006589,
443704960, 835506582, 5363460, 2068343250, 1683915700, 2080735477, 1913489530, 951256529, 1752318678, 105384223, 1788389051, 1787391786, 1430821640, 540952308, 882484999, 690806365, 202502890, 1593837351, 530093821, 385878401,
907401151, 378912543, 454746323, 251514112, 1451277631, 1125822965, 21289266, 1642884452, 804368379, 2048205721, 917508270, 1514792012, 139494505, 1143168018, 115016418, 1730333306, 1630776459, 50748643, 1745247524, 1313640711,
1076198976, 1820281480, 941471466, 806673335, 722162727, 1837280287, 705508794, 2088955494, 510497580, 51692325, 893597382, 1373978529, 1007042224, 685006165, 1471461419, 1555325521, 1215063385, 1424859828, 657251271, 1391827090,
965562483, 604275115, 1285258674, 341475746, 294191106, 633240394, 1897691227, 1904243956, 823532901, 1577955754, 2016464961, 1862876260, 577384103, 1012611702, 247243083, 636485510, 1952805989, 1447876480, 108021700, 1016615447,
2047769687, 943871886, 787537653, 12744598, 853545598, 334037304, 553373537, 1089408490, 497867498, 2038925801, 1434633879, 1290629443, 75922980, 957037315, 2130252471, 477317888, 952824381, 1686570783, 459340678, 751885764,
836307572, 2027909489, 28791588, 322748588, 1335236478, 787106123, 113580144, 954915740, 1317077622, 1299667896, 2009244921, 1548588723, 2049698913, 732388681, 1781891230, 2090684129, 993786972, 1959292396, 1336513734, 691093904,
1746904676, 935573751, 1123555638, 108413311, 1445352642, 169726789, 123352211, 1635952299, 673775121, 2042861943, 757787251, 512494446, 119656942, 58159196, 2090570016, 486181025, 1619641914, 432990571, 894937325, 379470588,
1890938638, 1886317932, 1858637614, 969358207, 1230449468, 1890889527, 351741654, 214725897, 1550012286, 308005013, 26292400, 68067591, 1383307838, 1746273091, 1090104632, 1658037573, 2081544705, 1133473813, 1680294422, 1050373352,
1806061681, 1713475126, 520699193, 417568373, 1355086853, 631399565, 1742434188, 2077667592, 1709019727, 594054971, 937081176, 742185643, 1904514273, 887841601, 1288684086, 424587711, 1497926365, 829844031, 1384314543, 250129297,
200083737, 693737559, 1527022962, 1462501905, 1687540458, 1156824624, 241481265, 1190890142, 1250360726, 2064308502, 27563032, 1880483834, 1984143440, 104727360, 1324123626, 1089710430, 1403206383, 1930880552, 773197243, 1160186023,
562994480, 1065136414, 502237764, 1642338733, 1310177444, 1730721241, 1475638246, 615734453, 1160537912, 928836931, 253898558, 1799210492, 1205522527, 413058646, 1589194592, 1774218355, 43955934, 1673314595, 683393460, 1260859787,
2098829619, 772503535, 1232567659, 758174758, 831270563, 1605294199, 1660678300, 24379565, 1426483935, 1611558740, 1085326591, 12849216, 455856722, 878692218, 1910978116, 1382893830, 1950124297, 950009818, 904287249, 791384486,
1584408128, 210098472, 1110387095, 364620240, 53868166, 772251062, 472745168, 1133910514, 1715402379, 1445225855, 1541125975, 149171217, 972058766, 1893095488, 1487620835, 640835502, 1470285405, 646688705, 988431201, 703130341,
1753125385, 1985895474, 696002734, 1783233173, 1317201705, 1755204784, 532132334, 1069450170, 249700039, 524320231, 757959820, 2109052886, 604977130, 1971654864, 1588222158, 1533496974, 623670976, 1405668251, 1955436051, 1082881617,
1387039848, 874153641, 1345378476, 1168465459, 2005021017, 234039217, 473318229, 654912216, 1473166451, 997649666, 801824335, 2052343947, 1883168929, 185658088, 1389954587, 1725541486, 885873448, 958774566, 2054212564, 60536525,
1427504270, 1160285859, 1827651881, 1408805003, 1684018729, 61716770, 844057079, 1011596733, 1521350211, 1581801257, 907554175, 2022973269, 1125104871, 1312064004, 1466679625, 970194422, 80900939, 1445279202, 335456148, 510478312,
92860378, 1646704157, 1650899832, 1533447203, 268087516, 880688023, 1180525723, 1868151949, 1750955971, 401446720, 540093580, 1022861633, 461442838, 1222554291, 456462271, 94760711, 1231111410, 2145073408, 1932108837, 300618464,
2055783490, 980863365, 1308872551, 1010427073, 1399854717, 1217804021, 934700736, 878744414
};
type verify_data[DATA_SIZE] =
{
690983, 900852, 2196420, 2530146, 3159407, 3522194, 3794415, 4031164, 5309142, 5363460, 9736243, 11476473, 12744598, 12849216, 12937811, 13180701, 13887419, 14125900, 14239125, 16411608,
19227407, 20643769, 21289266, 22136821, 22762734, 23288667, 24379565, 25885333, 26292400, 26687179, 27377406, 27563032, 28256901, 28791588, 30992839, 31153367, 31574181, 31596852, 35595330, 35859252,
37017340, 37141933, 38620214, 41714278, 42021322, 43955934, 47036070, 47452797, 47463938, 48311975, 48775768, 50748643, 50968578, 51692325, 53868166, 55461678, 58159196, 58217952, 59384706, 60536525,
61716770, 62209567, 63244522, 64795664, 66579049, 68067591, 69118708, 69889880, 70003859, 70894786, 72319656, 72802865, 72939206, 74887898, 75922980, 77104822, 77482422, 78348530, 80321564, 80404202,
80900939, 81402251, 82879528, 84924801, 87897457, 88823122, 89400484, 90063199, 91177380, 92271196, 92620223, 92860378, 93191015, 94760711, 95752736, 99511825, 104637677, 104727360, 105384223, 106223060,
106595511, 107095939, 107160610, 108021700, 108346070, 108413311, 108628319, 109035776, 109526756, 112035400, 112648605, 113462155, 113580144, 114202152, 115016418, 116766659, 117260224, 117280545, 117766047, 119285206,
119656942, 122124863, 123352211, 123889599, 127867199, 128036841, 130001148, 131405125, 133790520, 134453363, 135012885, 135678410, 137046551, 137796456, 139494505, 140536987, 145611377, 146002907, 148113917, 148527979,
149171217, 150878039, 151416112, 152273285, 155845605, 156498369, 156760399, 161450336, 161502390, 163362230, 167653495, 168771888, 169293723, 169726789, 170281493, 172109594, 173062659, 173822937, 174082258, 174965839,
175753599, 175843632, 176024101, 177100916, 178901145, 180549009, 180599971, 181567810, 182598318, 183679578, 185592115, 185658088, 185979744, 186112992, 186178768, 188016786, 190215907, 190536346, 190807078, 193873940,
195379046, 196401930, 197964832, 198186681, 198233440, 200083737, 200253206, 202502890, 204514903, 205008108, 206653795, 208160226, 208433088, 210098472, 210748671, 210908782, 212046016, 212821393, 214725897, 215018112,
216435361, 216557804, 217762975, 218671081, 221330186, 221661515, 222529745, 225091211, 225908941, 225934851, 226723092, 226726100, 226906236, 226986415, 227427283, 227870124, 228960529, 229905664, 230340298, 230634042,
231181585, 232170581, 234039217, 236851791, 237020443, 238278880, 238566180, 239990424, 240618723, 241481265, 241537930, 241711645, 244709448, 244975305, 245334962, 247243083, 247447060, 247448424, 249700039, 250022739,
250129297, 250731366, 250859482, 251514112, 253898558, 255226842, 256210446, 256860662, 257728183, 258177907, 259768753, 259775677, 260267972, 260670135, 260674360, 260792255, 261556590, 265363198, 267174620, 268087516,
269167950, 270410557, 270814499, 271906847, 274746405, 277497333, 277942057, 279252402, 281317274, 283430575, 284658041, 287497702, 288054543, 289686472, 291298358, 293109484, 294191106, 295666215, 298799048, 299505702,
300191208, 300618464, 301350822, 301663421, 301673313, 302219842, 303845878, 304131252, 304211060, 304427548, 305489695, 305750851, 308005013, 308700094, 308832070, 308857120, 310273032, 311127477, 316479300, 317980803,
318750634, 320137025, 322748588, 324215873, 325324443, 325667019, 328551896, 329049266, 329767814, 330474090, 331284679, 332201519, 333820982, 333906659, 334037304, 335456148, 336213879, 338532526, 340231765, 340442582,
341475746, 341674967, 341987235, 343038558, 343119399, 343682568, 344515114, 344860208, 346598567, 348131466, 349249331, 350182379, 351741654, 353946286, 355614494, 356546370, 356638683, 356672421, 359735266, 360632817,
362748128, 363508800, 364589031, 364620240, 365275089, 365854486, 366700722, 367923081, 368541415, 368889391, 371790550, 372280769, 372465453, 372501343, 373226849, 373305330, 375863194, 376781122, 378912543, 379470588,
380070610, 381094614, 381571915, 381933797, 382422699, 385878401, 386733714, 387061281, 387273799, 387611445, 388855203, 389233190, 390743779, 391321675, 395360213, 398211404, 398244682, 398911194, 399114073, 399456957,
399991238, 401446720, 402845420, 403378386, 407771887, 411864717, 413058646, 416457166, 417568373, 419053054, 419109342, 419476096, 420106224, 421198539, 422047044, 423299667, 424587711, 430093707, 432102601, 432609664,
432990571, 433412593, 434850545, 435236973, 435288306, 436476038, 436580096, 436630343, 437710825, 438711458, 443704960, 444361278, 446372159, 448284065, 448708980, 451448729, 452888789, 454359988, 454438520, 454746323,
455856722, 456462271, 459340678, 460420451, 460893030, 461442838, 461527795, 462743614, 462857778, 464171383, 464795711, 465119445, 470090505, 472745168, 472872107, 473318229, 477317888, 477407584, 478721193, 481561285,
481563348, 482917205, 483348027, 485818381, 486165509, 486181025, 487888229, 490920543, 492507266, 494367164, 495097609, 497867498, 498702377, 499898207, 500376868, 500734709, 502237764, 502323961, 502558280, 503368137,
503895325, 506466155, 507848158, 507936866, 508041515, 509116230, 509744705, 510478312, 510497580, 512494446, 513009937, 513561613, 513582947, 514214340, 514914429, 515414188, 515811664, 517767440, 518073650, 519194709,
519344323, 519699747, 520329478, 520511102, 520699193, 522160389, 522408049, 524320231, 525605961, 528024121, 529233847, 530093821, 532132334, 532467027, 533101409, 534384094, 535828217, 536063430, 538932155, 539429964,
539942311, 540006359, 540093580, 540952308, 542609105, 543952312, 544899032, 545066288, 545602285, 546340809, 548632788, 549253917, 550532376, 553373537, 556328195, 559509624, 560663378, 562994480, 565150174, 566166447,
567779677, 568652142, 569949159, 571635069, 572240371, 574236644, 576906032, 577384103, 577410402, 578787063, 579174666, 580464203, 580692625, 583112200, 585169793, 585804640, 589049769, 590690783, 592006699, 592234826,
594054971, 594814862, 595717488, 597427397, 598016845, 602368560, 602907378, 603159718, 603907009, 604275115, 604977130, 607471900, 607761482, 612289854, 614222093, 614612685, 615734453, 617768643, 617995659, 618168829,
618681206, 619428858, 619461174, 619972089, 620497725, 621921213, 622114437, 622170346, 623670976, 623909040, 624614472, 624714335, 624939139, 625991894, 628445699, 630393584, 631022494, 631399565, 631936923, 632611704,
633075975, 633240394, 636485510, 637659983, 638167485, 640835502, 644293952, 644842409, 646688705, 649754857, 650513248, 651536866, 651750790, 652078020, 652404808, 653050943, 653626077, 654912216, 655200896, 655445946,
656954306, 657251271, 661318748, 664387510, 665601851, 666624765, 670621648, 671848647, 672323245, 672906535, 673775121, 674580901, 675549432, 675663963, 677220745, 678475375, 679519053, 680172541, 682018288, 683393460,
683536723, 685006165, 686797873, 687941098, 688338919, 688483428, 690710531, 690806365, 690865719, 691093904, 692845661, 693737559, 696002734, 696188251, 696448050, 697685269, 697817760, 697866347, 698660475, 700725671,
701959731, 702380578, 703130341, 705508794, 705851791, 706357381, 706825946, 706913763, 709651138, 714042223, 714456194, 715940689, 717911282, 720339756, 721046824, 721524505, 722162727, 722260205, 722347551, 722919148,
723323690, 723930558, 726141970, 726869128, 727587915, 729474445, 729509794, 730090881, 730296520, 730422541, 730845665, 731606176, 731763278, 732388681, 732444124, 736455241, 737377568, 737518341, 738682048, 739596391,
740536012, 741078359, 741184696, 742185643, 743572345, 743745539, 745183293, 745777837, 747592875, 748527394, 749415493, 750631050, 750919339, 751885764, 752388169, 753296935, 754215794, 754247044, 754896618, 755554593,
755798022, 757787251, 757959820, 758174758, 761851297, 762564955, 764902582, 764935753, 765386206, 765701205, 767233910, 767880329, 768185796, 769005536, 770412991, 770957259, 772059719, 772251062, 772503535, 773197243,
777433215, 778702716, 778834747, 779093898, 783427298, 785398708, 785989696, 786297537, 786566648, 787106123, 787537653, 787842886, 787913688, 790256415, 790929190, 791188057, 791384486, 793505636, 795915364, 797060176,
798445606, 799527371, 799717076, 800591831, 800661980, 801046035, 801610475, 801824335, 802730854, 804368379, 806384435, 806638567, 806673335, 809604334, 810387144, 810516965, 812094461, 812288356, 812328969, 813511681,
814302898, 815110420, 817417567, 820933470, 821481684, 822635252, 823532901, 827496819, 829450571, 829844031, 830595166, 831270563, 831273447, 832081018, 833019845, 834410115, 835063788, 835506582, 836307572, 836983022,
837024327, 837554186, 839507573, 840106059, 843738737, 844057079, 845698678, 846127236, 846650758, 847255974, 848141854, 848402819, 849489374, 851322111, 851716534, 852338021, 852388468, 852835634, 853545598, 854475547,
855107605, 856621012, 856837002, 857894203, 858045289, 858150908, 859385989, 859612092, 860360715, 863551327, 863647665, 866097476, 866478506, 866854601, 866964848, 867628573, 869853078, 871908043, 873623623, 873976891,
874153641, 875481479, 876130333, 878692218, 878744414, 878884686, 879380479, 879552408, 879878312, 880456526, 880688023, 881982271, 882282387, 882484999, 885873448, 886978116, 887841601, 890461390, 891710357, 892574149,
892939912, 893302687, 893597382, 893957771, 894769708, 894937325, 895080280, 895562064, 898893218, 901789102, 904287249, 906899219, 907401151, 907554175, 909273561, 909415369, 910677024, 912381406, 914906004, 915948205,
916073297, 917508270, 918378387, 919736727, 921573402, 922186026, 923478775, 923768127, 924541465, 925604268, 925975225, 926200942, 926939064, 927045887, 927524181, 928179911, 928836931, 929351822, 930367387, 932423857,
933603111, 933673987, 934048997, 934700736, 935490932, 935573751, 935689637, 935939763, 937081176, 937976428, 937987129, 939497524, 941471466, 942977997, 943871886, 944382193, 945948973, 946311527, 946425090, 946489895,
948686793, 949010757, 949222447, 950009818, 951256529, 951663731, 952824381, 953383750, 953877041, 954441852, 954915740, 954942098, 957037315, 958774566, 959354209, 960982228, 964348374, 965490116, 965562483, 966363087,
968848252, 969076419, 969305448, 969358207, 969500483, 970194422, 972058766, 973367349, 973490494, 973493986, 973769771, 976015092, 976063110, 977454680, 977907387, 978247260, 980702956, 980863365, 983043723, 985305323,
986240059, 987761406, 988431201, 991159735, 991874801, 992410365, 993525189, 993786972, 994291574, 997649666, 998931662, 999229412, 999346398, 999899279, 1007042224, 1010427073, 1011417836, 1011473945, 1011596733, 1012611702,
1013901419, 1016469330, 1016615447, 1020037994, 1021014457, 1022861633, 1025117441, 1026342885, 1026380990, 1027758817, 1027760887, 1028529524, 1028820236, 1028937430, 1029176122, 1029338154, 1029832956, 1031625002, 1032748996, 1032914339,
1033910502, 1035075488, 1035956563, 1037521069, 1038018856, 1038830638, 1042790263, 1042942541, 1043920511, 1044088643, 1045627895, 1045658065, 1047336724, 1048943084, 1049475248, 1050373352, 1050512245, 1051184301, 1054066034, 1057003814,
1058677375, 1058937717, 1061864942, 1063657548, 1063743848, 1063768444, 1063839036, 1065136414, 1065481253, 1066014062, 1066787659, 1067775613, 1068587688, 1068798385, 1069450170, 1073695485, 1073871430, 1074205225, 1075762632, 1076198976,
1078197595, 1079859867, 1082499152, 1082864732, 1082881617, 1085326591, 1087195269, 1087245613, 1087251698, 1087556673, 1087742330, 1089408490, 1089710430, 1090104632, 1090386021, 1090443335, 1092382563, 1092881031, 1094283114, 1094531762,
1095403694, 1099847920, 1100041120, 1100089300, 1101722351, 1101933540, 1102423908, 1102603775, 1103013140, 1106678970, 1110387095, 1111213862, 1112056034, 1112731797, 1113693824, 1120963974, 1121432739, 1121800211, 1121960111, 1122768484,
1123331233, 1123555638, 1125104871, 1125822965, 1126017956, 1127173529, 1127911377, 1128895624, 1130850177, 1131661227, 1132597050, 1133473813, 1133910514, 1134185180, 1135793759, 1136264020, 1136356724, 1137511396, 1139018167, 1139159604,
1140008063, 1140728569, 1143168018, 1143511498, 1143853106, 1144017176, 1144669754, 1147341731, 1147793249, 1148699143, 1149113346, 1150780072, 1152335090, 1152416171, 1154842325, 1155459206, 1155544307, 1156824624, 1157666831, 1159675637,
1159745061, 1159898528, 1160036198, 1160186023, 1160285859, 1160333307, 1160537912, 1161580432, 1162679490, 1165446977, 1166227930, 1167207852, 1168465459, 1169327477, 1170510314, 1170759710, 1171051384, 1171925835, 1172290275, 1173840088,
1173889730, 1174587016, 1175004233, 1175885101, 1178086274, 1178260876, 1179525294, 1180063064, 1180525723, 1181191604, 1183464058, 1184561748, 1185825535, 1188076819, 1188748563, 1189141368, 1189323192, 1190890142, 1191079043, 1191513656,
1192155877, 1194041213, 1194709162, 1198213061, 1198254803, 1198857033, 1199317660, 1201124879, 1201152163, 1201659316, 1202009920, 1202162389, 1203377492, 1203897636, 1204992245, 1205522527, 1205895814, 1206302514, 1209784819, 1209991461,
1212628403, 1212974417, 1214379246, 1214950832, 1215063385, 1215103809, 1216475831, 1217804021, 1218522465, 1220523503, 1220915309, 1221108420, 1221726287, 1222554291, 1223475486, 1223572435, 1223583276, 1228817775, 1230449468, 1231111410,
1231149357, 1231249235, 1231639101, 1231932661, 1232567659, 1232992084, 1233022905, 1234157881, 1234944834, 1239665569, 1240287664, 1245819051, 1247518755, 1249086623, 1249183285, 1250360726, 1255524953, 1256015513, 1256152080, 1256372950,
1257507406, 1260859787, 1262399341, 1267173039, 1269707634, 1271370220, 1273223611, 1273955724, 1274190723, 1274436639, 1275331596, 1275500498, 1276205250, 1278053582, 1278777407, 1278794420, 1279061703, 1279981214, 1281443423, 1285258674,
1286989824, 1287171290, 1287830283, 1288684086, 1289308008, 1290629443, 1290969161, 1291025252, 1291070368, 1291438802, 1292049996, 1292413659, 1293091635, 1294873695, 1296857499, 1298200648, 1299667896, 1302272656, 1302724177, 1303736105,
1305071296, 1308872551, 1310177444, 1312064004, 1312471120, 1313115559, 1313640711, 1313871880, 1316120929, 1317077622, 1317201705, 1318032594, 1318900244, 1319798607, 1321897861, 1322281086, 1322696419, 1323798820, 1324123626, 1324723894,
1325008187, 1325083914, 1326017288, 1328272543, 1328885292, 1331383316, 1331593955, 1332379148, 1332467446, 1332620900, 1332937015, 1333790305, 1334857284, 1335236478, 1335298265, 1335652095, 1335861008, 1336108161, 1336513734, 1337406065,
1338090388, 1339293088, 1340949553, 1344125357, 1345014111, 1345378476, 1345873587, 1345987999, 1347284277, 1348361229, 1348373925, 1350653461, 1352833750, 1353144470, 1353999206, 1355086853, 1355391150, 1356847855, 1361012693, 1361078114,
1365423458, 1367731096, 1368235387, 1370528050, 1372169786, 1373978529, 1374125186, 1375470750, 1377995642, 1379259015, 1379460673, 1379995885, 1382429941, 1382484003, 1382551511, 1382893830, 1383307838, 1383640563, 1384314543, 1385675177,
1386258142, 1386366954, 1387039848, 1387864976, 1388759892, 1389787451, 1389954587, 1390040163, 1390274260, 1390306889, 1390477985, 1390656632, 1391095995, 1391827090, 1392162662, 1394929399, 1395155215, 1395289708, 1396662140, 1399673078,
1399854717, 1400070607, 1400929335, 1401058771, 1401980800, 1402735006, 1403206383, 1403771494, 1404727477, 1405668251, 1405763119, 1407094080, 1408805003, 1409001936, 1412540552, 1413860940, 1414141069, 1414160501, 1415390230, 1417415680,
1417601340, 1420810050, 1424797596, 1424859828, 1426483935, 1427504270, 1428223489, 1430821640, 1431492783, 1431814151, 1434046375, 1434633879, 1435859758, 1437147036, 1440145706, 1441811554, 1444048519, 1444076976, 1445225855, 1445279202,
1445352642, 1447469119, 1447876480, 1450892344, 1451277631, 1451442832, 1453397990, 1455316979, 1455756978, 1457464894, 1459100749, 1459138745, 1459500136, 1459620801, 1462192184, 1462501905, 1462778368, 1462921857, 1463269859, 1466632447,
1466679625, 1467376771, 1468486929, 1470285405, 1471131758, 1471461419, 1471598258, 1472567100, 1473166451, 1473735214, 1475638246, 1480273562, 1480324438, 1480437960, 1482983072, 1485740112, 1486594282, 1487620835, 1489699243, 1491477359,
1492071476, 1492488573, 1496078411, 1496277718, 1497680539, 1497926365, 1498554338, 1500102591, 1501181424, 1502266386, 1502480836, 1502557594, 1504023310, 1505022272, 1505475223, 1506716966, 1507433029, 1508705426, 1510133268, 1512135729,
1512163910, 1513255537, 1514278798, 1514582723, 1514792012, 1515262458, 1515528736, 1515933932, 1519017268, 1520667645, 1520886946, 1521350211, 1522316172, 1524006589, 1524491858, 1525451290, 1527022962, 1528031307, 1533447203, 1533496974,
1534330971, 1536213818, 1537459540, 1538069400, 1538391713, 1539560507, 1541125975, 1541132933, 1541546082, 1545555937, 1546057655, 1546104436, 1547662666, 1548588723, 1548804416, 1550012286, 1550159640, 1550525411, 1550721460, 1551661799,
1553547892, 1554106660, 1555325521, 1555660285, 1558244592, 1558695709, 1560142576, 1561212123, 1561251584, 1561422777, 1561730727, 1563717683, 1564061243, 1565610678, 1565700239, 1566878909, 1568176414, 1568395337, 1568900638, 1569479928,
1570645300, 1571598133, 1572212863, 1575380740, 1577034674, 1577955754, 1579725218, 1581062145, 1581118537, 1581801257, 1584408128, 1585050246, 1588222158, 1588715179, 1589194592, 1590461855, 1590771096, 1593359038, 1593837351, 1594621666,
1596042792, 1596821127, 1597506096, 1598436917, 1599565995, 1599876594, 1600023202, 1600493361, 1601134240, 1601247294, 1601617797, 1602517354, 1602827413, 1602967659, 1603428054, 1604330946, 1604357658, 1605294199, 1605369007, 1607204293,
1607515830, 1607628402, 1607677838, 1609955669, 1610244183, 1610539590, 1611500622, 1611558740, 1611680320, 1612593993, 1612609979, 1614780688, 1617229086, 1618378831, 1619598456, 1619641914, 1620562432, 1620803320, 1622692876, 1622758049,
1624653209, 1627355806, 1628387880, 1628389501, 1629633514, 1629914848, 1630293700, 1630776459, 1631405417, 1631935240, 1633512617, 1634445325, 1635952299, 1636203720, 1636860706, 1640952769, 1642338733, 1642884452, 1643991754, 1644353864,
1645969422, 1646704157, 1648575360, 1649344003, 1649392096, 1650899832, 1652108025, 1653332243, 1655277291, 1656527154, 1657001479, 1658037573, 1659079595, 1659137391, 1660678300, 1663100626, 1663890071, 1665914525, 1666074170, 1667102296,
1667679197, 1672192305, 1673314595, 1674045273, 1675300017, 1675494182, 1677449797, 1678967663, 1679324299, 1679777458, 1680251429, 1680294422, 1681866717, 1682700783, 1683915700, 1684018729, 1685350721, 1685880008, 1686215900, 1686479103,
1686570783, 1687540458, 1687941280, 1688652157, 1689946986, 1690167792, 1691486500, 1691676526, 1695191950, 1695617313, 1697686200, 1702425249, 1704561346, 1705378439, 1705905941, 1706528514, 1708002892, 1708106609, 1708126014, 1709019727,
1709697877, 1709823304, 1710305778, 1711569347, 1711718534, 1711761015, 1711765426, 1712269139, 1712341869, 1713188647, 1713475126, 1714295540, 1715279374, 1715379173, 1715402379, 1716853034, 1719009954, 1719573683, 1721767511, 1723143470,
1725541486, 1726987516, 1727583308, 1730333306, 1730721241, 1731949250, 1732028080, 1733366374, 1733982669, 1737931879, 1738353358, 1740099311, 1740778973, 1740783613, 1742032331, 1742434188, 1745247524, 1745393357, 1745543275, 1746273091,
1746476698, 1746904676, 1747861289, 1749972876, 1750197960, 1750443194, 1750955971, 1752088215, 1752318678, 1752598186, 1753125385, 1754447491, 1755204784, 1757028186, 1758748737, 1760851607, 1761289401, 1763785295, 1764436465, 1765354961,
1765830270, 1767380006, 1768795266, 1770497338, 1771614266, 1771924274, 1772760484, 1774218355, 1774652096, 1774796872, 1775331228, 1775608361, 1775805177, 1776471922, 1776794410, 1778544166, 1781233744, 1781891230, 1783233173, 1783943137,
1784682542, 1787338655, 1787391786, 1788389051, 1790557628, 1792756324, 1793190956, 1793747608, 1797641070, 1799210492, 1800186189, 1800522575, 1802197319, 1802327778, 1803183394, 1806061681, 1807085904, 1807172811, 1808237662, 1811088032,
1815408878, 1816641611, 1817156134, 1820281480, 1821482472, 1821559709, 1822279764, 1822612008, 1823053058, 1826590258, 1826628136, 1826880531, 1827651881, 1833543700, 1833603743, 1834161399, 1834254978, 1834285819, 1834318089, 1834388383,
1834852613, 1835203128, 1835860030, 1835977906, 1836119534, 1837280287, 1838218199, 1839063567, 1840896199, 1846605728, 1847908587, 1848681194, 1849495275, 1849657867, 1849675857, 1852181952, 1855359256, 1858637614, 1858933377, 1859683061,
1860435620, 1860839427, 1862876260, 1864952910, 1866094167, 1868151949, 1868289345, 1869264274, 1870214195, 1870859970, 1871060346, 1871684562, 1873900475, 1874026715, 1874855959, 1876255297, 1878253960, 1878434988, 1879635915, 1880483834,
1880577483, 1881253854, 1883168929, 1883999260, 1886317932, 1890889527, 1890938638, 1891630185, 1891904961, 1892370478, 1893095488, 1896952705, 1897691227, 1897907456, 1898582764, 1900162831, 1900613055, 1901537567, 1902501708, 1902595458,
1904243956, 1904514273, 1904576737, 1904770864, 1905279500, 1906345724, 1907793490, 1908093581, 1909681194, 1910978116, 1912065710, 1913489530, 1913581092, 1913926325, 1914764659, 1914809801, 1915435344, 1916602098, 1918354829, 1920182565,
1924603748, 1926717418, 1927367009, 1928309762, 1928550562, 1930662128, 1930880552, 1931282005, 1931493432, 1932108837, 1933532372, 1933923245, 1935271536, 1936668087, 1938258683, 1939683211, 1942089394, 1943137808, 1943651015, 1944679691,
1945110368, 1946004194, 1948121717, 1949896838, 1950124297, 1951228823, 1952177514, 1952364329, 1952805989, 1953450944, 1953919896, 1955436051, 1957728250, 1957877704, 1958396887, 1959222232, 1959292396, 1961619988, 1961647235, 1962689485,
1963053072, 1965358941, 1965855212, 1967705762, 1968608155, 1968623233, 1969729134, 1970797151, 1971484382, 1971654864, 1977865396, 1980923963, 1981481446, 1983379601, 1984143440, 1984152603, 1985895474, 1986921372, 1989240516, 1992941115,
1994402695, 1997381015, 2001056977, 2002881120, 2004664325, 2004770236, 2005021017, 2005653265, 2005817027, 2006320950, 2006856683, 2009244921, 2010549018, 2011827638, 2014090929, 2014129292, 2015847175, 2016161810, 2016464961, 2017191527,
2018336444, 2022291557, 2022973269, 2023498746, 2024853642, 2027445678, 2027814180, 2027828650, 2027909489, 2028116487, 2029133999, 2029909894, 2033003588, 2033828953, 2034767768, 2036061488, 2036750157, 2037182006, 2038925801, 2039012903,
2041942843, 2042861943, 2044016080, 2045407567, 2045821218, 2046759770, 2047006719, 2047769687, 2048205721, 2048560397, 2049698913, 2052321529, 2052328978, 2052343947, 2053899162, 2054212564, 2055783490, 2060969286, 2061144988, 2063408339,
2064145552, 2064308502, 2066440075, 2066865713, 2067100479, 2067499753, 2068343250, 2068743361, 2069178089, 2070467093, 2072440819, 2073482870, 2074840378, 2074896270, 2076612603, 2077667592, 2078528215, 2079492652, 2080735477, 2081544705,
2082760612, 2084953915, 2085323316, 2087660971, 2088576982, 2088786920, 2088955494, 2089981667, 2090025563, 2090543533, 2090570016, 2090684129, 2091626028, 2093472294, 2094085507, 2094159153, 2094591332, 2094864173, 2097057488, 2098829619,
2100497812, 2103236982, 2105321510, 2105638337, 2105718728, 2105814934, 2108439398, 2109052886, 2109530615, 2109851473, 2113434968, 2114587535, 2115445751, 2116495484, 2117880007, 2118203528, 2118433006, 2118805956, 2118821565, 2119425672,
2122262571, 2122852959, 2123379476, 2124749673, 2125958841, 2126029304, 2126940990, 2126963607, 2128078174, 2128826472, 2129513521, 2129930580, 2130252471, 2130879949, 2131761201, 2131797509, 2133066804, 2135673182, 2139976479, 2140091269,
2140756121, 2141591317, 2142357746, 2143324534, 2143343312, 2143968639, 2145073408, 2145930822
};

View file

@ -0,0 +1,122 @@
// See LICENSE for license details.
//**************************************************************************
// Quicksort benchmark
//--------------------------------------------------------------------------
//
// This benchmark uses quicksort to sort an array of integers. The
// implementation is largely adapted from Numerical Recipes for C. The
// input data (and reference data) should be generated using the
// qsort_gendata.pl perl script and dumped to a file named
// dataset1.h
#include "util.h"
#include <string.h>
#include <limits.h>
//--------------------------------------------------------------------------
// Input/Reference Data
#define type unsigned int
#include "dataset1.h"
#define LOG_BASE 8
#define BASE (1 << LOG_BASE)
#if 0
# define fetch_add(ptr, inc) __sync_fetch_and_add(ptr, inc)
#else
# define fetch_add(ptr, inc) ((*(ptr) += (inc)) - (inc))
#endif
void sort(size_t n, type* arrIn, type* scratchIn)
{
size_t log_exp = 0;
size_t buckets[BASE];
size_t *bucket = buckets;
asm("":"+r"(bucket));
type *arr = arrIn, *scratch = scratchIn, *p;
size_t *b;
while (log_exp < CHAR_BIT * sizeof(type))
{
for (b = bucket; b < bucket + BASE; b++)
*b = 0;
for (p = arr; p < &arr[n-3]; p += 4)
{
type a0 = p[0];
type a1 = p[1];
type a2 = p[2];
type a3 = p[3];
fetch_add(&bucket[(a0 >> log_exp) % BASE], 1);
fetch_add(&bucket[(a1 >> log_exp) % BASE], 1);
fetch_add(&bucket[(a2 >> log_exp) % BASE], 1);
fetch_add(&bucket[(a3 >> log_exp) % BASE], 1);
}
for ( ; p < &arr[n]; p++)
bucket[(*p >> log_exp) % BASE]++;
size_t prev = bucket[0];
prev += fetch_add(&bucket[1], prev);
for (b = &bucket[2]; b < bucket + BASE; b += 2)
{
prev += fetch_add(&b[0], prev);
prev += fetch_add(&b[1], prev);
}
static_assert(BASE % 2 == 0);
for (p = &arr[n-1]; p >= &arr[3]; p -= 4)
{
type a0 = p[-0];
type a1 = p[-1];
type a2 = p[-2];
type a3 = p[-3];
size_t* pb0 = &bucket[(a0 >> log_exp) % BASE];
size_t* pb1 = &bucket[(a1 >> log_exp) % BASE];
size_t* pb2 = &bucket[(a2 >> log_exp) % BASE];
size_t* pb3 = &bucket[(a3 >> log_exp) % BASE];
type* s0 = scratch + fetch_add(pb0, -1);
type* s1 = scratch + fetch_add(pb1, -1);
type* s2 = scratch + fetch_add(pb2, -1);
type* s3 = scratch + fetch_add(pb3, -1);
s0[-1] = a0;
s1[-1] = a1;
s2[-1] = a2;
s3[-1] = a3;
}
for ( ; p >= &arr[0]; p--)
scratch[--bucket[(*p >> log_exp) % BASE]] = *p;
type* tmp = arr;
arr = scratch;
scratch = tmp;
log_exp += LOG_BASE;
}
if (arr != arrIn)
memcpy(arr, scratch, n*sizeof(type));
}
//--------------------------------------------------------------------------
// Main
int main( int argc, char* argv[] )
{
static type scratch[DATA_SIZE];
#if PREALLOCATE
// If needed we preallocate everything in the caches
sort(DATA_SIZE, verify_data, scratch);
if (verify(DATA_SIZE, input_data, input_data))
return 1;
#endif
// Do the sort
setStats(1);
sort(DATA_SIZE, input_data, scratch);
setStats(0);
// Check the results
return verify( DATA_SIZE, input_data, verify_data );
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,48 @@
#!/usr/bin/env scala
!#
val m = args(0).toInt
val n = args(1).toInt
val approx_nnz = args(2).toInt
val pnnz = approx_nnz.toDouble/(m*n)
val idx = collection.mutable.ArrayBuffer[Int]()
val p = collection.mutable.ArrayBuffer(0)
for (i <- 0 until m) {
for (j <- 0 until n) {
if (util.Random.nextDouble < pnnz)
idx += j
}
p += idx.length
}
val nnz = idx.length
val v = Array.tabulate(n)(i => util.Random.nextInt(1000))
val d = Array.tabulate(nnz)(i => util.Random.nextInt(1000))
def printVec(t: String, name: String, data: Seq[Int]) = {
println("const " + t + " " + name + "[" + data.length + "] = {")
println(" "+data.map(_.toString).reduceLeft(_+",\n "+_))
println("};")
}
def spmv(p: Seq[Int], d: Seq[Int], idx: Seq[Int], v: Seq[Int]) = {
val y = collection.mutable.ArrayBuffer[Int]()
for (i <- 0 until p.length-1) {
var yi = 0
for (k <- p(i) until p(i+1))
yi = yi + d(k)*v(idx(k))
y += yi
}
y
}
println("#define R " + m)
println("#define C " + n)
println("#define NNZ " + nnz)
printVec("double", "val", d)
printVec("int", "idx", idx)
printVec("double", "x", v)
printVec("int", "ptr", p)
printVec("double", "verify_data", spmv(p, d, idx, v))

View file

@ -0,0 +1,52 @@
// See LICENSE for license details.
//**************************************************************************
// Double-precision sparse matrix-vector multiplication benchmark
//--------------------------------------------------------------------------
#include "util.h"
//--------------------------------------------------------------------------
// Input/Reference Data
#include "dataset1.h"
void spmv(int r, const double* val, const int* idx, const double* x,
const int* ptr, double* y)
{
for (int i = 0; i < r; i++)
{
int k;
double yi0 = 0, yi1 = 0, yi2 = 0, yi3 = 0;
for (k = ptr[i]; k < ptr[i+1]-3; k+=4)
{
yi0 += val[k+0]*x[idx[k+0]];
yi1 += val[k+1]*x[idx[k+1]];
yi2 += val[k+2]*x[idx[k+2]];
yi3 += val[k+3]*x[idx[k+3]];
}
for ( ; k < ptr[i+1]; k++)
{
yi0 += val[k]*x[idx[k]];
}
y[i] = (yi0+yi1)+(yi2+yi3);
}
}
//--------------------------------------------------------------------------
// Main
int main( int argc, char* argv[] )
{
double y[R];
#if PREALLOCATE
spmv(R, val, idx, x, ptr, y);
#endif
setStats(1);
spmv(R, val, idx, x, ptr, y);
setStats(0);
return verifyDouble(R, y, verify_data);
}

View file

@ -0,0 +1,234 @@
// See LICENSE for license details.
//**************************************************************************
// Towers of Hanoi benchmark
//--------------------------------------------------------------------------
//
// Towers of Hanoi is a classic puzzle problem. The game consists of
// three pegs and a set of discs. Each disc is a different size, and
// initially all of the discs are on the left most peg with the smallest
// disc on top and the largest disc on the bottom. The goal is to move all
// of the discs onto the right most peg. The catch is that you are only
// allowed to move one disc at a time and you can never place a larger
// disc on top of a smaller disc.
//
// This implementation starts with NUM_DISC discs and uses a recursive
// algorithm to sovel the puzzle.
#include "util.h"
// This is the number of discs in the puzzle.
#define NUM_DISCS 7
//--------------------------------------------------------------------------
// List data structure and functions
struct Node
{
int val;
struct Node* next;
};
struct List
{
int size;
struct Node* head;
};
struct List g_nodeFreeList;
struct Node g_nodePool[NUM_DISCS];
int list_getSize( struct List* list )
{
return list->size;
}
void list_init( struct List* list )
{
list->size = 0;
list->head = 0;
}
void list_push( struct List* list, int val )
{
struct Node* newNode;
// Pop the next free node off the free list
newNode = g_nodeFreeList.head;
g_nodeFreeList.head = g_nodeFreeList.head->next;
// Push the new node onto the given list
newNode->next = list->head;
list->head = newNode;
// Assign the value
list->head->val = val;
// Increment size
list->size++;
}
int list_pop( struct List* list )
{
struct Node* freedNode;
int val;
// Get the value from the->head of given list
val = list->head->val;
// Pop the head node off the given list
freedNode = list->head;
list->head = list->head->next;
// Push the freed node onto the free list
freedNode->next = g_nodeFreeList.head;
g_nodeFreeList.head = freedNode;
// Decrement size
list->size--;
return val;
}
void list_clear( struct List* list )
{
while ( list_getSize(list) > 0 )
list_pop(list);
}
//--------------------------------------------------------------------------
// Tower data structure and functions
struct Towers
{
int numDiscs;
int numMoves;
struct List pegA;
struct List pegB;
struct List pegC;
};
void towers_init( struct Towers* this, int n )
{
int i;
this->numDiscs = n;
this->numMoves = 0;
list_init( &(this->pegA) );
list_init( &(this->pegB) );
list_init( &(this->pegC) );
for ( i = 0; i < n; i++ )
list_push( &(this->pegA), n-i );
}
void towers_clear( struct Towers* this )
{
list_clear( &(this->pegA) );
list_clear( &(this->pegB) );
list_clear( &(this->pegC) );
towers_init( this, this->numDiscs );
}
void towers_solve_h( struct Towers* this, int n,
struct List* startPeg,
struct List* tempPeg,
struct List* destPeg )
{
int val;
if ( n == 1 ) {
val = list_pop(startPeg);
list_push(destPeg,val);
this->numMoves++;
}
else {
towers_solve_h( this, n-1, startPeg, destPeg, tempPeg );
towers_solve_h( this, 1, startPeg, tempPeg, destPeg );
towers_solve_h( this, n-1, tempPeg, startPeg, destPeg );
}
}
void towers_solve( struct Towers* this )
{
towers_solve_h( this, this->numDiscs, &(this->pegA), &(this->pegB), &(this->pegC) );
}
int towers_verify( struct Towers* this )
{
struct Node* ptr;
int numDiscs = 0;
if ( list_getSize(&this->pegA) != 0 ) {
return 2;
}
if ( list_getSize(&this->pegB) != 0 ) {
return 3;
}
if ( list_getSize(&this->pegC) != this->numDiscs ) {
return 4;
}
for ( ptr = this->pegC.head; ptr != 0; ptr = ptr->next ) {
numDiscs++;
if ( ptr->val != numDiscs ) {
return 5;
}
}
if ( this->numMoves != ((1 << this->numDiscs) - 1) ) {
return 6;
}
return 0;
}
//--------------------------------------------------------------------------
// Main
int main( int argc, char* argv[] )
{
struct Towers towers;
int i;
// Initialize free list
list_init( &g_nodeFreeList );
g_nodeFreeList.head = &(g_nodePool[0]);
g_nodeFreeList.size = NUM_DISCS;
g_nodePool[NUM_DISCS-1].next = 0;
g_nodePool[NUM_DISCS-1].val = 99;
for ( i = 0; i < (NUM_DISCS-1); i++ ) {
g_nodePool[i].next = &(g_nodePool[i+1]);
g_nodePool[i].val = i;
}
towers_init( &towers, NUM_DISCS );
// If needed we preallocate everything in the caches
#if PREALLOCATE
towers_solve( &towers );
#endif
// Solve it
towers_clear( &towers );
setStats(1);
towers_solve( &towers );
setStats(0);
// Check the results
return towers_verify( &towers );
}

View file

@ -0,0 +1,167 @@
// See LICENSE for license details.
#define DATA_SIZE 1000
int input1_data[DATA_SIZE] =
{
41, 833, 564, 187, 749, 350, 132, 949, 584, 805, 621, 6, 931, 890, 392, 694, 961, 110, 116, 296,
426, 314, 659, 774, 319, 678, 875, 376, 474, 938, 539, 569, 203, 280, 759, 606, 511, 657, 195, 81,
267, 229, 337, 944, 902, 241, 913, 826, 933, 985, 195, 960, 566, 350, 649, 657, 181, 111, 859, 65,
288, 349, 141, 905, 886, 264, 576, 979, 761, 241, 478, 499, 403, 222, 444, 721, 676, 317, 224, 937,
288, 119, 615, 606, 389, 351, 455, 278, 367, 358, 584, 62, 985, 403, 346, 517, 559, 908, 775, 255,
778, 598, 143, 33, 125, 941, 933, 799, 553, 431, 648, 952, 287, 19, 49, 86, 95, 441, 587, 614,
382, 280, 808, 971, 819, 344, 450, 512, 965, 347, 808, 882, 537, 946, 701, 356, 567, 891, 22, 568,
665, 423, 434, 158, 2, 84, 247, 49, 435, 792, 869, 486, 414, 369, 548, 518, 888, 682, 284, 264,
499, 290, 897, 215, 731, 688, 251, 786, 555, 302, 528, 544, 322, 947, 287, 824, 304, 788, 733, 959,
366, 722, 294, 975, 653, 748, 91, 378, 105, 102, 381, 651, 825, 840, 356, 148, 54, 140, 955, 343,
533, 757, 521, 837, 592, 13, 173, 63, 121, 133, 758, 372, 951, 39, 129, 110, 847, 437, 255, 269,
409, 628, 399, 549, 753, 564, 171, 19, 727, 501, 777, 43, 753, 81, 202, 853, 153, 760, 357, 943,
922, 328, 496, 442, 516, 641, 276, 786, 113, 842, 907, 275, 237, 32, 784, 565, 357, 803, 819, 751,
280, 85, 458, 454, 710, 459, 41, 253, 377, 508, 700, 860, 480, 741, 499, 709, 49, 371, 873, 945,
992, 526, 721, 435, 232, 497, 697, 30, 348, 250, 350, 250, 573, 784, 749, 502, 823, 826, 170, 160,
674, 32, 202, 143, 853, 90, 394, 107, 855, 106, 157, 6, 765, 204, 194, 574, 218, 526, 177, 239,
698, 757, 706, 49, 84, 799, 893, 512, 373, 492, 14, 621, 83, 103, 794, 921, 643, 880, 834, 239,
462, 114, 561, 529, 10, 997, 904, 387, 407, 105, 559, 936, 512, 409, 302, 202, 427, 613, 359, 521,
684, 22, 185, 312, 107, 274, 387, 242, 486, 105, 698, 899, 770, 644, 80, 161, 407, 946, 30, 768,
870, 113, 148, 62, 147, 838, 845, 432, 141, 211, 817, 821, 562, 364, 615, 495, 812, 916, 159, 430,
803, 180, 544, 840, 458, 786, 872, 795, 806, 758, 104, 401, 254, 984, 136, 729, 584, 794, 414, 528,
707, 554, 378, 766, 977, 236, 947, 229, 165, 505, 105, 704, 796, 140, 303, 795, 635, 560, 119, 8,
532, 814, 37, 584, 739, 619, 767, 478, 57, 958, 784, 985, 837, 307, 67, 824, 996, 749, 171, 826,
621, 155, 826, 43, 694, 80, 236, 747, 744, 265, 124, 731, 941, 425, 370, 320, 269, 542, 763, 752,
915, 14, 1, 906, 995, 809, 560, 873, 972, 289, 509, 558, 970, 405, 579, 293, 251, 849, 129, 452,
716, 86, 678, 181, 240, 335, 793, 641, 1, 320, 987, 646, 754, 958, 203, 142, 180, 299, 165, 761,
974, 646, 559, 619, 422, 260, 565, 542, 492, 991, 745, 207, 372, 932, 664, 34, 533, 478, 908, 203,
33, 214, 365, 892, 781, 680, 705, 688, 947, 386, 50, 101, 474, 399, 679, 330, 952, 471, 477, 725,
713, 937, 529, 870, 77, 545, 907, 853, 143, 979, 239, 105, 365, 98, 54, 98, 440, 764, 315, 336,
697, 774, 726, 324, 282, 536, 622, 594, 890, 75, 290, 496, 726, 449, 548, 135, 644, 838, 290, 767,
162, 415, 491, 985, 116, 617, 859, 235, 282, 571, 913, 560, 194, 242, 782, 985, 728, 344, 430, 613,
759, 176, 309, 333, 354, 310, 699, 46, 487, 503, 100, 393, 268, 314, 75, 345, 987, 600, 908, 384,
92, 545, 277, 668, 351, 853, 863, 312, 100, 532, 567, 836, 370, 989, 461, 912, 182, 268, 160, 771,
22, 854, 644, 17, 779, 911, 855, 137, 983, 717, 565, 719, 253, 785, 154, 196, 253, 447, 899, 5,
325, 616, 309, 175, 159, 123, 838, 715, 550, 230, 82, 627, 324, 927, 103, 17, 966, 159, 177, 593,
372, 393, 599, 745, 377, 865, 591, 553, 440, 345, 593, 290, 908, 544, 377, 456, 781, 110, 495, 896,
806, 700, 548, 340, 29, 829, 630, 546, 613, 972, 116, 313, 904, 971, 607, 794, 169, 896, 507, 916,
431, 339, 147, 224, 112, 580, 834, 134, 948, 201, 488, 396, 797, 478, 769, 574, 485, 339, 721, 451,
821, 744, 0, 594, 277, 120, 680, 757, 555, 847, 517, 379, 505, 904, 246, 243, 394, 430, 214, 244,
524, 399, 172, 304, 620, 594, 535, 698, 159, 750, 809, 454, 75, 93, 167, 16, 853, 494, 324, 78,
52, 112, 10, 342, 730, 680, 287, 961, 92, 626, 912, 616, 860, 744, 744, 478, 615, 508, 914, 810,
288, 974, 129, 581, 548, 868, 981, 270, 623, 653, 626, 990, 386, 323, 472, 164, 239, 189, 865, 231,
356, 152, 825, 328, 390, 848, 38, 402, 616, 546, 206, 2, 783, 890, 815, 831, 665, 410, 94, 246,
422, 211, 675, 9, 374, 426, 64, 53, 758, 811, 500, 437, 335, 328, 237, 415, 468, 684, 565, 305,
449, 597, 136, 882, 383, 938, 268, 115, 908, 50, 952, 366, 397, 257, 231, 667, 35, 990, 443, 213,
389, 13, 621, 52, 612, 934, 953, 828, 462, 621, 812, 522, 672, 57, 313, 352, 55, 972, 753, 416,
879, 864, 572, 163, 721, 12, 643, 507, 968, 781, 840, 242, 630, 810, 795, 435, 885, 599, 696, 643,
93, 710, 785, 112, 581, 12, 923, 615, 652, 359, 261, 233, 609, 686, 539, 118, 560, 739, 20, 317,
976, 573, 386, 772, 663, 504, 212, 888, 907, 420, 737, 516, 25, 219, 797, 716, 452, 692, 683, 459,
815, 323, 612, 247, 116, 352, 281, 738, 290, 909, 645, 625, 932, 220, 685, 373, 876, 646, 412, 955
};
int input2_data[DATA_SIZE] =
{
454, 335, 1, 989, 365, 572, 64, 153, 216, 140, 210, 572, 339, 593, 898, 228, 12, 883, 750, 646,
500, 436, 701, 812, 981, 150, 696, 564, 272, 258, 647, 509, 88, 703, 669, 375, 551, 936, 592, 569,
952, 800, 584, 643, 368, 489, 328, 313, 592, 388, 543, 649, 979, 997, 814, 79, 208, 998, 629, 847,
704, 997, 253, 715, 430, 415, 538, 700, 4, 494, 100, 864, 693, 416, 296, 285, 620, 78, 351, 540,
646, 169, 527, 289, 796, 801, 720, 758, 745, 92, 989, 271, 853, 788, 531, 222, 461, 241, 358, 332,
684, 740, 446, 311, 743, 557, 479, 557, 925, 796, 357, 891, 666, 514, 557, 870, 853, 440, 61, 678,
396, 9, 17, 170, 291, 380, 536, 185, 917, 539, 983, 887, 54, 612, 951, 479, 151, 7, 641, 335,
730, 95, 728, 280, 395, 688, 911, 476, 815, 729, 265, 127, 236, 214, 180, 6, 503, 596, 173, 643,
346, 599, 68, 849, 658, 619, 121, 131, 828, 667, 433, 487, 753, 125, 626, 14, 10, 403, 106, 703,
818, 964, 406, 874, 856, 86, 60, 660, 667, 153, 121, 98, 412, 236, 12, 423, 965, 216, 621, 361,
921, 715, 647, 299, 886, 682, 36, 493, 551, 537, 969, 643, 434, 415, 303, 438, 860, 203, 478, 988,
675, 719, 990, 338, 450, 633, 155, 646, 452, 427, 509, 988, 426, 12, 483, 142, 339, 390, 50, 171,
601, 105, 968, 121, 879, 81, 870, 600, 603, 871, 887, 610, 404, 234, 745, 526, 275, 441, 226, 752,
943, 726, 709, 201, 54, 758, 53, 397, 41, 141, 416, 747, 219, 478, 770, 180, 482, 691, 725, 173,
186, 914, 1, 963, 247, 464, 362, 521, 233, 120, 40, 779, 195, 161, 743, 439, 355, 403, 141, 633,
289, 782, 320, 636, 118, 852, 70, 816, 388, 954, 36, 16, 698, 695, 677, 598, 883, 824, 746, 462,
511, 534, 440, 428, 732, 726, 702, 547, 86, 798, 215, 21, 651, 59, 429, 657, 96, 973, 659, 966,
524, 62, 625, 303, 714, 409, 55, 728, 305, 436, 901, 592, 691, 796, 497, 177, 940, 995, 480, 158,
822, 611, 680, 14, 111, 797, 185, 0, 718, 96, 749, 739, 814, 435, 326, 37, 33, 605, 935, 27,
88, 441, 339, 344, 554, 365, 954, 639, 396, 991, 249, 338, 832, 974, 393, 266, 470, 348, 336, 419,
249, 215, 542, 903, 636, 729, 581, 820, 671, 979, 418, 670, 920, 568, 745, 662, 139, 385, 927, 173,
457, 316, 183, 477, 196, 399, 416, 805, 996, 270, 735, 696, 825, 528, 50, 623, 537, 87, 294, 867,
110, 398, 781, 646, 375, 943, 897, 589, 44, 288, 845, 742, 99, 522, 443, 432, 165, 930, 28, 461,
323, 272, 376, 340, 898, 158, 168, 443, 193, 631, 935, 274, 781, 185, 619, 292, 933, 156, 827, 88,
987, 629, 649, 32, 1, 744, 399, 915, 791, 554, 984, 530, 600, 401, 683, 540, 903, 120, 995, 521,
622, 224, 895, 530, 820, 651, 226, 96, 262, 569, 238, 126, 610, 191, 238, 796, 884, 573, 108, 140,
789, 852, 23, 704, 890, 480, 52, 372, 201, 546, 408, 119, 645, 464, 81, 293, 52, 880, 224, 744,
735, 886, 167, 1, 532, 321, 169, 485, 101, 177, 42, 708, 654, 915, 625, 242, 822, 795, 641, 252,
245, 151, 876, 333, 601, 938, 775, 397, 233, 755, 454, 424, 210, 962, 900, 923, 655, 529, 595, 90,
464, 685, 70, 754, 32, 494, 25, 389, 488, 37, 409, 639, 27, 950, 539, 80, 303, 723, 734, 125,
552, 248, 107, 362, 48, 869, 144, 841, 724, 335, 470, 263, 343, 809, 677, 339, 336, 410, 465, 56,
590, 485, 406, 993, 746, 238, 525, 336, 256, 134, 546, 722, 367, 943, 106, 629, 396, 208, 429, 523,
130, 355, 990, 673, 991, 719, 449, 84, 616, 211, 707, 737, 847, 452, 316, 974, 746, 796, 522, 618,
115, 727, 226, 165, 200, 830, 742, 187, 705, 671, 785, 886, 962, 657, 293, 620, 144, 173, 796, 72,
678, 80, 793, 685, 637, 967, 241, 898, 693, 372, 601, 721, 398, 553, 72, 174, 978, 325, 558, 185,
505, 859, 651, 573, 321, 349, 400, 890, 844, 885, 933, 980, 448, 989, 50, 332, 900, 716, 747, 444,
6, 394, 285, 703, 450, 652, 771, 485, 534, 559, 481, 507, 434, 343, 42, 784, 865, 421, 415, 871,
539, 162, 105, 481, 595, 115, 350, 964, 287, 232, 154, 602, 539, 943, 872, 121, 652, 811, 747, 362,
340, 910, 206, 572, 505, 973, 961, 354, 627, 849, 971, 910, 410, 770, 63, 874, 396, 482, 619, 646,
557, 328, 67, 884, 512, 972, 6, 513, 882, 562, 764, 366, 506, 786, 831, 382, 638, 452, 72, 83,
59, 932, 929, 924, 961, 69, 797, 985, 854, 885, 600, 389, 232, 793, 179, 773, 689, 775, 494, 139,
234, 431, 780, 371, 22, 653, 741, 815, 428, 139, 603, 315, 344, 889, 317, 260, 861, 377, 511, 304,
70, 35, 854, 576, 490, 326, 303, 431, 813, 708, 388, 962, 967, 442, 49, 831, 251, 321, 741, 179,
176, 117, 523, 764, 952, 704, 531, 804, 23, 611, 846, 375, 854, 971, 24, 639, 318, 723, 662, 647,
281, 158, 294, 885, 734, 866, 471, 296, 673, 472, 439, 5, 155, 506, 948, 600, 445, 222, 784, 349,
943, 150, 366, 444, 604, 720, 340, 972, 911, 321, 435, 50, 78, 761, 950, 238, 27, 226, 201, 176,
877, 450, 879, 99, 143, 31, 812, 771, 527, 488, 797, 194, 293, 966, 276, 345, 413, 197, 386, 116,
322, 680, 538, 553, 960, 874, 48, 506, 898, 539, 495, 764, 805, 286, 432, 836, 192, 825, 778, 586,
359, 352, 746, 11, 749, 5, 408, 643, 441, 368, 97, 169, 359, 527, 672, 69, 880, 298, 300, 327,
923, 829, 816, 497, 243, 981, 917, 713, 653, 503, 406, 543, 108, 304, 464, 954, 86, 802, 446, 28
};
int verify_data[DATA_SIZE] =
{
495, 1168, 565, 1176, 1114, 922, 196, 1102, 800, 945, 831, 578, 1270, 1483, 1290, 922, 973, 993, 866, 942,
926, 750, 1360, 1586, 1300, 828, 1571, 940, 746, 1196, 1186, 1078, 291, 983, 1428, 981, 1062, 1593, 787, 650,
1219, 1029, 921, 1587, 1270, 730, 1241, 1139, 1525, 1373, 738, 1609, 1545, 1347, 1463, 736, 389, 1109, 1488, 912,
992, 1346, 394, 1620, 1316, 679, 1114, 1679, 765, 735, 578, 1363, 1096, 638, 740, 1006, 1296, 395, 575, 1477,
934, 288, 1142, 895, 1185, 1152, 1175, 1036, 1112, 450, 1573, 333, 1838, 1191, 877, 739, 1020, 1149, 1133, 587,
1462, 1338, 589, 344, 868, 1498, 1412, 1356, 1478, 1227, 1005, 1843, 953, 533, 606, 956, 948, 881, 648, 1292,
778, 289, 825, 1141, 1110, 724, 986, 697, 1882, 886, 1791, 1769, 591, 1558, 1652, 835, 718, 898, 663, 903,
1395, 518, 1162, 438, 397, 772, 1158, 525, 1250, 1521, 1134, 613, 650, 583, 728, 524, 1391, 1278, 457, 907,
845, 889, 965, 1064, 1389, 1307, 372, 917, 1383, 969, 961, 1031, 1075, 1072, 913, 838, 314, 1191, 839, 1662,
1184, 1686, 700, 1849, 1509, 834, 151, 1038, 772, 255, 502, 749, 1237, 1076, 368, 571, 1019, 356, 1576, 704,
1454, 1472, 1168, 1136, 1478, 695, 209, 556, 672, 670, 1727, 1015, 1385, 454, 432, 548, 1707, 640, 733, 1257,
1084, 1347, 1389, 887, 1203, 1197, 326, 665, 1179, 928, 1286, 1031, 1179, 93, 685, 995, 492, 1150, 407, 1114,
1523, 433, 1464, 563, 1395, 722, 1146, 1386, 716, 1713, 1794, 885, 641, 266, 1529, 1091, 632, 1244, 1045, 1503,
1223, 811, 1167, 655, 764, 1217, 94, 650, 418, 649, 1116, 1607, 699, 1219, 1269, 889, 531, 1062, 1598, 1118,
1178, 1440, 722, 1398, 479, 961, 1059, 551, 581, 370, 390, 1029, 768, 945, 1492, 941, 1178, 1229, 311, 793,
963, 814, 522, 779, 971, 942, 464, 923, 1243, 1060, 193, 22, 1463, 899, 871, 1172, 1101, 1350, 923, 701,
1209, 1291, 1146, 477, 816, 1525, 1595, 1059, 459, 1290, 229, 642, 734, 162, 1223, 1578, 739, 1853, 1493, 1205,
986, 176, 1186, 832, 724, 1406, 959, 1115, 712, 541, 1460, 1528, 1203, 1205, 799, 379, 1367, 1608, 839, 679,
1506, 633, 865, 326, 218, 1071, 572, 242, 1204, 201, 1447, 1638, 1584, 1079, 406, 198, 440, 1551, 965, 795,
958, 554, 487, 406, 701, 1203, 1799, 1071, 537, 1202, 1066, 1159, 1394, 1338, 1008, 761, 1282, 1264, 495, 849,
1052, 395, 1086, 1743, 1094, 1515, 1453, 1615, 1477, 1737, 522, 1071, 1174, 1552, 881, 1391, 723, 1179, 1341, 701,
1164, 870, 561, 1243, 1173, 635, 1363, 1034, 1161, 775, 840, 1400, 1621, 668, 353, 1418, 1172, 647, 413, 875,
642, 1212, 818, 1230, 1114, 1562, 1664, 1067, 101, 1246, 1629, 1727, 936, 829, 510, 1256, 1161, 1679, 199, 1287,
944, 427, 1202, 383, 1592, 238, 404, 1190, 937, 896, 1059, 1005, 1722, 610, 989, 612, 1202, 698, 1590, 840,
1902, 643, 650, 938, 996, 1553, 959, 1788, 1763, 843, 1493, 1088, 1570, 806, 1262, 833, 1154, 969, 1124, 973,
1338, 310, 1573, 711, 1060, 986, 1019, 737, 263, 889, 1225, 772, 1364, 1149, 441, 938, 1064, 872, 273, 901,
1763, 1498, 582, 1323, 1312, 740, 617, 914, 693, 1537, 1153, 326, 1017, 1396, 745, 327, 585, 1358, 1132, 947,
768, 1100, 532, 893, 1313, 1001, 874, 1173, 1048, 563, 92, 809, 1128, 1314, 1304, 572, 1774, 1266, 1118, 977,
958, 1088, 1405, 1203, 678, 1483, 1682, 1250, 376, 1734, 693, 529, 575, 1060, 954, 1021, 1095, 1293, 910, 426,
1161, 1459, 796, 1078, 314, 1030, 647, 983, 1378, 112, 699, 1135, 753, 1399, 1087, 215, 947, 1561, 1024, 892,
714, 663, 598, 1347, 164, 1486, 1003, 1076, 1006, 906, 1383, 823, 537, 1051, 1459, 1324, 1064, 754, 895, 669,
1349, 661, 715, 1326, 1100, 548, 1224, 382, 743, 637, 646, 1115, 635, 1257, 181, 974, 1383, 808, 1337, 907,
222, 900, 1267, 1341, 1342, 1572, 1312, 396, 716, 743, 1274, 1573, 1217, 1441, 777, 1886, 928, 1064, 682, 1389,
137, 1581, 870, 182, 979, 1741, 1597, 324, 1688, 1388, 1350, 1605, 1215, 1442, 447, 816, 397, 620, 1695, 77,
1003, 696, 1102, 860, 796, 1090, 1079, 1613, 1243, 602, 683, 1348, 722, 1480, 175, 191, 1944, 484, 735, 778,
877, 1252, 1250, 1318, 698, 1214, 991, 1443, 1284, 1230, 1526, 1270, 1356, 1533, 427, 788, 1681, 826, 1242, 1340,
812, 1094, 833, 1043, 479, 1481, 1401, 1031, 1147, 1531, 597, 820, 1338, 1314, 649, 1578, 1034, 1317, 922, 1787,
970, 501, 252, 705, 707, 695, 1184, 1098, 1235, 433, 642, 998, 1336, 1421, 1641, 695, 1137, 1150, 1468, 813,
1161, 1654, 206, 1166, 782, 1093, 1641, 1111, 1182, 1696, 1488, 1289, 915, 1674, 309, 1117, 790, 912, 833, 890,
1081, 727, 239, 1188, 1132, 1566, 541, 1211, 1041, 1312, 1573, 820, 581, 879, 998, 398, 1491, 946, 396, 161,
111, 1044, 939, 1266, 1691, 749, 1084, 1946, 946, 1511, 1512, 1005, 1092, 1537, 923, 1251, 1304, 1283, 1408, 949,
522, 1405, 909, 952, 570, 1521, 1722, 1085, 1051, 792, 1229, 1305, 730, 1212, 789, 424, 1100, 566, 1376, 535,
426, 187, 1679, 904, 880, 1174, 341, 833, 1429, 1254, 594, 964, 1750, 1332, 864, 1662, 916, 731, 835, 425,
598, 328, 1198, 773, 1326, 1130, 595, 857, 781, 1422, 1346, 812, 1189, 1299, 261, 1054, 786, 1407, 1227, 952,
730, 755, 430, 1767, 1117, 1804, 739, 411, 1581, 522, 1391, 371, 552, 763, 1179, 1267, 480, 1212, 1227, 562,
1332, 163, 987, 496, 1216, 1654, 1293, 1800, 1373, 942, 1247, 572, 750, 818, 1263, 590, 82, 1198, 954, 592,
1756, 1314, 1451, 262, 864, 43, 1455, 1278, 1495, 1269, 1637, 436, 923, 1776, 1071, 780, 1298, 796, 1082, 759,
415, 1390, 1323, 665, 1541, 886, 971, 1121, 1550, 898, 756, 997, 1414, 972, 971, 954, 752, 1564, 798, 903,
1335, 925, 1132, 783, 1412, 509, 620, 1531, 1348, 788, 834, 685, 384, 746, 1469, 785, 1332, 990, 983, 786,
1738, 1152, 1428, 744, 359, 1333, 1198, 1451, 943, 1412, 1051, 1168, 1040, 524, 1149, 1327, 962, 1448, 858, 983
};

View file

@ -0,0 +1,62 @@
// See LICENSE for license details.
#define DATA_SIZE 300
int input1_data[DATA_SIZE] =
{
41, 833, 564, 187, 749, 350, 132, 949, 584, 805, 621, 6, 931, 890, 392, 694, 961, 110, 116, 296,
426, 314, 659, 774, 319, 678, 875, 376, 474, 938, 539, 569, 203, 280, 759, 606, 511, 657, 195, 81,
267, 229, 337, 944, 902, 241, 913, 826, 933, 985, 195, 960, 566, 350, 649, 657, 181, 111, 859, 65,
288, 349, 141, 905, 886, 264, 576, 979, 761, 241, 478, 499, 403, 222, 444, 721, 676, 317, 224, 937,
288, 119, 615, 606, 389, 351, 455, 278, 367, 358, 584, 62, 985, 403, 346, 517, 559, 908, 775, 255,
778, 598, 143, 33, 125, 941, 933, 799, 553, 431, 648, 952, 287, 19, 49, 86, 95, 441, 587, 614,
382, 280, 808, 971, 819, 344, 450, 512, 965, 347, 808, 882, 537, 946, 701, 356, 567, 891, 22, 568,
665, 423, 434, 158, 2, 84, 247, 49, 435, 792, 869, 486, 414, 369, 548, 518, 888, 682, 284, 264,
499, 290, 897, 215, 731, 688, 251, 786, 555, 302, 528, 544, 322, 947, 287, 824, 304, 788, 733, 959,
366, 722, 294, 975, 653, 748, 91, 378, 105, 102, 381, 651, 825, 840, 356, 148, 54, 140, 955, 343,
533, 757, 521, 837, 592, 13, 173, 63, 121, 133, 758, 372, 951, 39, 129, 110, 847, 437, 255, 269,
409, 628, 399, 549, 753, 564, 171, 19, 727, 501, 777, 43, 753, 81, 202, 853, 153, 760, 357, 943,
922, 328, 496, 442, 516, 641, 276, 786, 113, 842, 907, 275, 237, 32, 784, 565, 357, 803, 819, 751,
280, 85, 458, 454, 710, 459, 41, 253, 377, 508, 700, 860, 480, 741, 499, 709, 49, 371, 873, 945,
992, 526, 721, 435, 232, 497, 697, 30, 348, 250, 350, 250, 573, 784, 749, 502, 823, 826, 170, 160
};
int input2_data[DATA_SIZE] =
{
454, 335, 1, 989, 365, 572, 64, 153, 216, 140, 210, 572, 339, 593, 898, 228, 12, 883, 750, 646,
500, 436, 701, 812, 981, 150, 696, 564, 272, 258, 647, 509, 88, 703, 669, 375, 551, 936, 592, 569,
952, 800, 584, 643, 368, 489, 328, 313, 592, 388, 543, 649, 979, 997, 814, 79, 208, 998, 629, 847,
704, 997, 253, 715, 430, 415, 538, 700, 4, 494, 100, 864, 693, 416, 296, 285, 620, 78, 351, 540,
646, 169, 527, 289, 796, 801, 720, 758, 745, 92, 989, 271, 853, 788, 531, 222, 461, 241, 358, 332,
684, 740, 446, 311, 743, 557, 479, 557, 925, 796, 357, 891, 666, 514, 557, 870, 853, 440, 61, 678,
396, 9, 17, 170, 291, 380, 536, 185, 917, 539, 983, 887, 54, 612, 951, 479, 151, 7, 641, 335,
730, 95, 728, 280, 395, 688, 911, 476, 815, 729, 265, 127, 236, 214, 180, 6, 503, 596, 173, 643,
346, 599, 68, 849, 658, 619, 121, 131, 828, 667, 433, 487, 753, 125, 626, 14, 10, 403, 106, 703,
818, 964, 406, 874, 856, 86, 60, 660, 667, 153, 121, 98, 412, 236, 12, 423, 965, 216, 621, 361,
921, 715, 647, 299, 886, 682, 36, 493, 551, 537, 969, 643, 434, 415, 303, 438, 860, 203, 478, 988,
675, 719, 990, 338, 450, 633, 155, 646, 452, 427, 509, 988, 426, 12, 483, 142, 339, 390, 50, 171,
601, 105, 968, 121, 879, 81, 870, 600, 603, 871, 887, 610, 404, 234, 745, 526, 275, 441, 226, 752,
943, 726, 709, 201, 54, 758, 53, 397, 41, 141, 416, 747, 219, 478, 770, 180, 482, 691, 725, 173,
186, 914, 1, 963, 247, 464, 362, 521, 233, 120, 40, 779, 195, 161, 743, 439, 355, 403, 141, 633
};
int verify_data[DATA_SIZE] =
{
495, 1168, 565, 1176, 1114, 922, 196, 1102, 800, 945, 831, 578, 1270, 1483, 1290, 922, 973, 993, 866, 942,
926, 750, 1360, 1586, 1300, 828, 1571, 940, 746, 1196, 1186, 1078, 291, 983, 1428, 981, 1062, 1593, 787, 650,
1219, 1029, 921, 1587, 1270, 730, 1241, 1139, 1525, 1373, 738, 1609, 1545, 1347, 1463, 736, 389, 1109, 1488, 912,
992, 1346, 394, 1620, 1316, 679, 1114, 1679, 765, 735, 578, 1363, 1096, 638, 740, 1006, 1296, 395, 575, 1477,
934, 288, 1142, 895, 1185, 1152, 1175, 1036, 1112, 450, 1573, 333, 1838, 1191, 877, 739, 1020, 1149, 1133, 587,
1462, 1338, 589, 344, 868, 1498, 1412, 1356, 1478, 1227, 1005, 1843, 953, 533, 606, 956, 948, 881, 648, 1292,
778, 289, 825, 1141, 1110, 724, 986, 697, 1882, 886, 1791, 1769, 591, 1558, 1652, 835, 718, 898, 663, 903,
1395, 518, 1162, 438, 397, 772, 1158, 525, 1250, 1521, 1134, 613, 650, 583, 728, 524, 1391, 1278, 457, 907,
845, 889, 965, 1064, 1389, 1307, 372, 917, 1383, 969, 961, 1031, 1075, 1072, 913, 838, 314, 1191, 839, 1662,
1184, 1686, 700, 1849, 1509, 834, 151, 1038, 772, 255, 502, 749, 1237, 1076, 368, 571, 1019, 356, 1576, 704,
1454, 1472, 1168, 1136, 1478, 695, 209, 556, 672, 670, 1727, 1015, 1385, 454, 432, 548, 1707, 640, 733, 1257,
1084, 1347, 1389, 887, 1203, 1197, 326, 665, 1179, 928, 1286, 1031, 1179, 93, 685, 995, 492, 1150, 407, 1114,
1523, 433, 1464, 563, 1395, 722, 1146, 1386, 716, 1713, 1794, 885, 641, 266, 1529, 1091, 632, 1244, 1045, 1503,
1223, 811, 1167, 655, 764, 1217, 94, 650, 418, 649, 1116, 1607, 699, 1219, 1269, 889, 531, 1062, 1598, 1118,
1178, 1440, 722, 1398, 479, 961, 1059, 551, 581, 370, 390, 1029, 768, 945, 1492, 941, 1178, 1229, 311, 793
};

View file

@ -0,0 +1,139 @@
#!/usr/bin/perl -w
#==========================================================================
# vvadd_gendata.pl
#
# Author : Christopher Batten (cbatten@mit.edu)
# Date : April 29, 2005
#
(our $usageMsg = <<'ENDMSG') =~ s/^\#//gm;
#
# Simple script which creates an input data set and the reference data
# for the vvadd benchmark.
#
ENDMSG
use strict "vars";
use warnings;
no warnings("once");
use Getopt::Long;
#--------------------------------------------------------------------------
# Command line processing
#--------------------------------------------------------------------------
our %opts;
sub usage()
{
print "\n";
print " Usage: vvadd_gendata.pl [options] \n";
print "\n";
print " Options:\n";
print " --help print this message\n";
print " --size size of input data [1000]\n";
print " --seed random seed [1]\n";
print "$usageMsg";
exit();
}
sub processCommandLine()
{
$opts{"help"} = 0;
$opts{"size"} = 1000;
$opts{"seed"} = 1;
Getopt::Long::GetOptions( \%opts, 'help|?', 'size:i', 'seed:i' ) or usage();
$opts{"help"} and usage();
}
#--------------------------------------------------------------------------
# Helper Functions
#--------------------------------------------------------------------------
sub printArray
{
my $arrayName = $_[0];
my $arrayRef = $_[1];
my $numCols = 20;
my $arrayLen = scalar(@{$arrayRef});
print "int ".$arrayName."[DATA_SIZE] = \n";
print "{\n";
if ( $arrayLen <= $numCols ) {
print " ";
for ( my $i = 0; $i < $arrayLen; $i++ ) {
print sprintf("%3d",$arrayRef->[$i]);
if ( $i != $arrayLen-1 ) {
print ", ";
}
}
print "\n";
}
else {
my $numRows = int($arrayLen/$numCols);
for ( my $j = 0; $j < $numRows; $j++ ) {
print " ";
for ( my $i = 0; $i < $numCols; $i++ ) {
my $index = $j*$numCols + $i;
print sprintf("%3d",$arrayRef->[$index]);
if ( $index != $arrayLen-1 ) {
print ", ";
}
}
print "\n";
}
if ( $arrayLen > ($numRows*$numCols) ) {
print " ";
for ( my $i = 0; $i < ($arrayLen-($numRows*$numCols)); $i++ ) {
my $index = $numCols*$numRows + $i;
print sprintf("%3d",$arrayRef->[$index]);
if ( $index != $arrayLen-1 ) {
print ", ";
}
}
print "\n";
}
}
print "};\n\n";
}
#--------------------------------------------------------------------------
# Main
#--------------------------------------------------------------------------
sub main()
{
processCommandLine();
srand($opts{"seed"});
my @values1;
my @values2;
my @sum;
for ( my $i = 0; $i < $opts{"size"}; $i++ ) {
my $value1 = int(rand(999));
my $value2 = int(rand(999));
push( @values1, $value1 );
push( @values2, $value2 );
push( @sum, $value1 + $value2 );
}
print "\n\#define DATA_SIZE ".$opts{"size"}." \n\n";
printArray( "input1_data", \@values1 );
printArray( "input2_data", \@values2 );
printArray( "verify_data", \@sum );
}
main();

View file

@ -0,0 +1,48 @@
// See LICENSE for license details.
//**************************************************************************
// Vector-vector add benchmark
//--------------------------------------------------------------------------
//
// This benchmark uses adds to vectors and writes the results to a
// third vector. The input data (and reference data) should be
// generated using the vvadd_gendata.pl perl script and dumped
// to a file named dataset1.h.
#include "util.h"
//--------------------------------------------------------------------------
// Input/Reference Data
#include "dataset1.h"
//--------------------------------------------------------------------------
// vvadd function
void vvadd( int n, int a[], int b[], int c[] )
{
int i;
for ( i = 0; i < n; i++ )
c[i] = a[i] + b[i];
}
//--------------------------------------------------------------------------
// Main
int main( int argc, char* argv[] )
{
int results_data[DATA_SIZE];
#if PREALLOCATE
// If needed we preallocate everything in the caches
vvadd( DATA_SIZE, input1_data, input2_data, results_data );
#endif
// Do the vvadd
setStats(1);
vvadd( DATA_SIZE, input1_data, input2_data, results_data );
setStats(0);
// Check the results
return verify( DATA_SIZE, results_data, verify_data );
}

3694
vendor/riscv-tests/configure vendored Executable file

File diff suppressed because it is too large Load diff

16
vendor/riscv-tests/configure.ac vendored Normal file
View file

@ -0,0 +1,16 @@
AC_INIT(riscv-tests, 1.0)
cross_compiling=yes
AC_PROG_CC
AC_ARG_WITH(xlen,
[AS_HELP_STRING([--with-xlen=XLEN],
[Set XLEN, the X-register bit width (default is 64)])],
AC_SUBST(XLEN, $withval),
AC_SUBST(XLEN, 64)
)
AC_OUTPUT(
Makefile
)

41
vendor/riscv-tests/debug/Makefile vendored Normal file
View file

@ -0,0 +1,41 @@
RISCV_SIM ?= spike
XLEN ?= 64
src_dir ?= .
GDBSERVER_PY = $(src_dir)/gdbserver.py
TESTS = $(shell $(GDBSERVER_PY) --list-tests $(src_dir)/targets/RISC-V/spike32.py)
MULTI_TESTS = $(shell $(GDBSERVER_PY) --list-tests $(src_dir)/targets/RISC-V/spike32.py | \
grep -i multi)
default: spike$(XLEN) spike$(XLEN)-2
all-tests: spike32 spike-multi-limited spike32-2 spike32-2-hwthread \
spike64 spike64-2 spike64-2-hwthread
slow-tests: spike-multi all-tests
all: pylint all-tests
run.%:
$(GDBSERVER_PY) \
$(src_dir)/targets/RISC-V/$(word 2, $(subst ., ,$@)).py \
$(word 3, $(subst ., ,$@)) \
--isolate \
--print-failures \
--sim_cmd $(RISCV)/bin/$(RISCV_SIM) \
--server_cmd $(RISCV)/bin/openocd
# Target to check all the multicore options.
multi-tests: spike32-2 spike32-2-hwthread
pylint:
pylint --rcfile=pylint.rc `git ls-files '*.py'`
spike-multi-limited: $(foreach test, $(MULTI_TESTS), run.spike-multi.$(test))
echo Finished $@
spike%: $(foreach test, $(TESTS), run.spike%.$(test))
echo Finished $@
clean:
rm -f *.pyc

58
vendor/riscv-tests/debug/README.md vendored Normal file
View file

@ -0,0 +1,58 @@
Debug Tests
===========
Debugging requires many system components to all work together. The tests here
perform an end-to-end test, communicating with gdb and OpenOCD.
If a simulator or hardware passes all these tests, then you can be pretty
confident that the actual debug interface is functioning correctly.
Requirements
============
The following should be in the user's path:
* riscv64-unknown-elf-gcc (`rvv-0.9.x` branch for riscv-gnu-toolchain should
work if master does not have vector support yet)
* riscv64-unknown-elf-gdb (can be overridden with `--gdb` when running
gdbserver.py manually), which should be the latest from
git://sourceware.org/git/binutils-gdb.git.
* spike (can be overridden with `--sim_cmd` when running gdbserver.py
manually), which should be the latest from
https://github.com/riscv/riscv-isa-sim.git.
* openocd (can be overridden with `--server_cmd` when running gdbserver.py
manually), which should be the latest from
https://github.com/riscv/riscv-openocd.git.
Usage
=====
To run a quick smoke test against spike, run `make`. For a more comprehensive
test against a variety of spike configurations, run `make all`.
To run tests against hardware, or a specific spike configuration, manually
invoke gdbserver.py: `./gdbserver.py targets/<file>.py`
You can run just a single test by specifying any part of its name on the
command line, eg: `./gdbserver.py targets/RISC-V/spike64.py S0` runs
SimpleS0Test. Once that test has failed, you can look at the log file to get
an idea of what might have gone wrong.
For custom targets, you can create a .py file anywhere and pass its path on the
command line. The Targets class in `targets.py` contains documentation on what
every variable means.
Log Files
=========
All output from tests ends up in the `logs/` subdirectory, with one log file
per test. If a test fails, this is where to look.
Debug Tips
==========
You can see what spike is doing by adding `-l` to the spike command, eg.:
`./gdbserver.py --sim_cmd "$RISCV/bin/spike -l" targets/RISC-V/spike32.py Breakpoint`
You can see what OpenOCD is doing by adding `-d` to the OpenOCD command, eg.:
`./gdbserver.py --server_cmd "openocd -d" targets/RISC-V/spike32.py Breakpoint`
You can run gdb under valgrind by passing --gdb, eg.: `./gdbserver.py
--gdb "valgrind riscv64-unknown-elf-gdb" targets/RISC-V/spike64.py
DownloadTest`

View file

@ -0,0 +1,7 @@
This directory contains binaries that are not easy to compile.
RTOSDemo32.axf and RTOSDemo64.axf are created by checking out
https://github.com/FreeRTOS/FreeRTOS, following the instructions in
`FreeRTOS/Demo/RISC-V-spike-htif_GCC/README.md`, and building:
* `make XLEN=32 BASE_ADDRESS=0x10100000`
* `make XLEN=64 BASE_ADDRESS=0x1212340000`

Binary file not shown.

Binary file not shown.

2031
vendor/riscv-tests/debug/gdbserver.py vendored Executable file

File diff suppressed because it is too large Load diff

85
vendor/riscv-tests/debug/openocd.py vendored Executable file
View file

@ -0,0 +1,85 @@
#!/usr/bin/env python
"""Test that OpenOCD can talk to a RISC-V target."""
import argparse
import sys
import targets
import testlib
from testlib import assertIn, assertEqual
class OpenOcdTest(testlib.BaseTest):
def __init__(self, target):
testlib.BaseTest.__init__(self, target)
self.gdb = None
def early_applicable(self):
return self.target.openocd_config
def setup(self):
# pylint: disable=attribute-defined-outside-init
self.cli = testlib.OpenocdCli()
self.cli.command("halt")
def write_nops(self, count):
for address in range(self.target.ram, self.target.ram + 4 * count, 4):
# 0x13 is nop
self.cli.command(f"mww 0x{address:x} 0x13")
class RegTest(OpenOcdTest):
def test(self):
self.write_nops(4)
regs = self.cli.reg()
assertIn("x18", regs)
self.cli.command("reg x18 0x11782")
self.cli.command(f"step 0x{self.target.ram:x}")
assertEqual(self.cli.reg("x18"), 0x11782)
class StepTest(OpenOcdTest):
def test(self):
self.write_nops(4)
self.cli.command("step 0x{self.target.ram:x}")
for i in range(4):
pc = self.cli.reg("pc")
assertEqual(pc, self.target.ram + 4 * (i+1))
self.cli.command("step")
class ResumeTest(OpenOcdTest):
def test(self):
self.write_nops(16)
self.cli.command(f"bp 0x{self.target.ram + 12:x} 4")
self.cli.command(f"bp 0x{self.target.ram + 24:x} 4")
self.cli.command(f"resume 0x{self.target.ram:x}")
assertEqual(self.cli.reg("pc"), self.target.ram + 12)
self.cli.command("resume")
assertEqual(self.cli.reg("pc"), self.target.ram + 24)
self.cli.command(f"resume 0x{self.target.ram:x}")
assertEqual(self.cli.reg("pc"), self.target.ram + 12)
def main():
parser = argparse.ArgumentParser(
description="Test that OpenOCD can talk to a RISC-V target.")
targets.add_target_options(parser)
testlib.add_test_run_options(parser)
parsed = parser.parse_args()
target = parsed.target(parsed.server_cmd, parsed.sim_cmd, parsed.isolate)
if parsed.xlen:
target.xlen = parsed.xlen
module = sys.modules[__name__]
return testlib.run_all_tests(module, target, parsed)
if __name__ == '__main__':
sys.exit(main())

View file

@ -0,0 +1,38 @@
#include <stdint.h>
// CRC code from http://www.hackersdelight.org/hdcodetxt/crc.c.txt
// Reverses (reflects) bits in a 32-bit word.
unsigned reverse(unsigned x) {
x = ((x & 0x55555555) << 1) | ((x >> 1) & 0x55555555);
x = ((x & 0x33333333) << 2) | ((x >> 2) & 0x33333333);
x = ((x & 0x0F0F0F0F) << 4) | ((x >> 4) & 0x0F0F0F0F);
x = (x << 24) | ((x & 0xFF00) << 8) |
((x >> 8) & 0xFF00) | (x >> 24);
return x;
}
// ----------------------------- crc32a --------------------------------
/* This is the basic CRC algorithm with no optimizations. It follows the
logic circuit as closely as possible. */
unsigned int crc32a(uint8_t *message, unsigned int size) {
int i, j;
unsigned int byte, crc;
i = 0;
crc = 0xFFFFFFFF;
while (i < size) {
byte = message[i]; // Get next byte.
byte = reverse(byte); // 32-bit reversal.
for (j = 0; j <= 7; j++) { // Do eight times.
if ((int)(crc ^ byte) < 0)
crc = (crc << 1) ^ 0x04C11DB7;
else crc = crc << 1;
byte = byte << 1; // Ready next msg bit.
}
i = i + 1;
}
return reverse(~crc);
}

View file

@ -0,0 +1,17 @@
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
int main()
{
int sum = 0;
int counter = 0;
while (counter < 10) {
counter = counter + 1;
sum = sum + counter;
}
return counter;
}

View file

@ -0,0 +1,71 @@
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
unsigned int crc32a(uint8_t *message, unsigned int size);
unsigned int fib(unsigned int n)
{
if (n == 0) {
return 0;
}
unsigned int a = 0;
unsigned int b = 1;
for (unsigned int i = 1; i < n; i++) {
unsigned int next = a + b;
a = b;
b = next;
}
return b;
}
void rot13(char *buf)
{
while (*buf) {
if ((*buf >= 'a' && *buf <= 'm') ||
(*buf >= 'A' && *buf <= 'M')) {
*buf += 13;
} else if ((*buf >= 'n' && *buf <= 'z') ||
(*buf >= 'N' && *buf <= 'Z')) {
*buf -= 13;
}
buf++;
}
}
size_t strlen(const char *buf)
{
int len = 0;
while (buf[len])
len++;
return len;
}
extern void *__malloc_freelist;
int main()
{
__malloc_freelist = 0;
volatile int i = 0;
int j = 0;
char *fox = "The quick brown fox jumps of the lazy dog.";
unsigned int checksum = 0;
volatile uint32_t i32 = 0xdeadbeef;
volatile uint64_t i64 = 0x1122334455667788;
start:
while (i)
j++;
rot13(fox);
checksum ^= crc32a(fox, strlen(fox));
rot13(fox);
checksum ^= crc32a(fox, strlen(fox));
return checksum;
}

View file

@ -0,0 +1,31 @@
#include <stdint.h>
void ebreak()
{
asm volatile("ebreak");
}
unsigned int fib(unsigned int n)
{
if (n == 0) {
return 0;
}
unsigned int a = 0;
unsigned int b = 1;
for (unsigned int i = 1; i < n; i++) {
unsigned int next = a + b;
a = b;
b = next;
ebreak();
}
return b;
}
int main()
{
begin:
fib(4);
}

226
vendor/riscv-tests/debug/programs/entry.S vendored Executable file
View file

@ -0,0 +1,226 @@
#include "encoding.h"
#define STACK_SIZE (90 * XLEN / 8)
#if XLEN == 64
# define LREG ld
# define SREG sd
# define REGBYTES 8
#else
# define LREG lw
# define SREG sw
# define REGBYTES 4
#endif
.section .text.entry
.globl _start
_start:
j handle_reset
nmi_vector:
j nmi_vector
trap_vector:
j trap_entry
handle_reset:
// If misa doesn't exist (or is following an old spec where it has a
// different number), skip the next block.
la t0, 3f
csrw mtvec, t0
csrwi mstatus, 0
// make sure these registers exist by seeing if either S or U bits
// are set before attempting to zero them out.
csrr t1, misa
addi t2, x0, 1
slli t2, t2, 20 // U_EXTENSION
and t2, t1, t2
bne x0, t2, 1f
addi t2, x0, 1
slli t2, t2, 18 // S_EXTENSION
and t2, t1, t2
bne x0, t2, 1f
j 2f
1:
csrwi mideleg, 0
csrwi medeleg, 0
2:
csrwi mie, 0
3:
la t0, trap_entry
csrw mtvec, t0
csrwi mstatus, 0
# initialize global pointer
.option push
.option norelax
la gp, __global_pointer$
.option pop
# Initialize stack pointer.
la sp, stack_bottom
# Give each hart STACK_SIZE of stack.
# Assume hart IDs are contiguous and start at 0.
li t1, STACK_SIZE
csrr t0, CSR_MHARTID
# Don't use mul instruction because not all harts support it.
addi t0, t0, 1
1:
add sp, sp, t1
addi t0, t0, -1
bnez t0, 1b
# Catch trap in case trigger module is not implemented
la t2, 2f
csrrw t2, mtvec, t2
# Clear all hardware triggers
li t0, ~0
1:
addi t0, t0, 1
csrw CSR_TSELECT, t0
csrw CSR_TDATA1, zero
csrr t1, CSR_TSELECT
beq t0, t1, 1b
.p2align 2
2:
# Restore mtvec
csrw mtvec, t2
#ifdef MULTICORE
csrr t0, CSR_MHARTID
bnez t0, wait_until_initialized
#endif
la t0, __bss_start
la t1, __bss_end
1:
bge t0, t1, 2f
sb zero, 0(t0)
addi t0, t0, 1
j 1b
2:
#ifdef MULTICORE
la t0, initialized
li t1, 1
sw t1, 0(t0)
wait_until_initialized: # Wait for hart 0 to perform initialization.
la t0, initialized
1:
lw t1, 0(t0)
beqz t1, 1b
#endif
# perform the rest of initialization in C
j _init
.align 2
trap_entry:
addi sp, sp, -32*REGBYTES
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)
#ifndef RV32E
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)
#endif
csrr a0, mcause
csrr a1, mepc
mv a2, sp
jal handle_trap
csrw mepc, a0
# Remain in M-mode after mret
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)
#ifndef RV32E
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)
#endif
addi sp, sp, 32*REGBYTES
mret
loop_forever:
j loop_forever
.align 2
precease:
// Loop a while so that OpenOCD might have confirmed the resume before the
// hart becomes unavailable.
li t1, 100000
1:
addi t1, t1, -1
bnez t1, 1b
cease:
.word 0x30500073 // cease
j loop_forever
// Fill the stack with data so we can see if it was overrun.
.section .data
.align 4
stack_bottom:
.fill NHARTS * STACK_SIZE/4, 4, 0x22446688
stack_top:
initialized:
.word 0

View file

@ -0,0 +1,44 @@
#include "encoding.h"
.global main
.global main_end
.global main_post_csrr
// Load constants into all registers so we can test no register are
// clobbered after attaching.
main:
csrr x1, CSR_MHARTID
slli x1, x1, 8
main_post_csrr:
addi x2, x1, 1
addi x3, x2, 1
addi x4, x3, 1
addi x5, x4, 1
addi x6, x5, 1
addi x7, x6, 1
addi x8, x7, 1
addi x9, x8, 1
addi x10, x9, 1
addi x11, x10, 1
addi x12, x11, 1
addi x13, x12, 1
addi x14, x13, 1
addi x15, x14, 1
addi x16, x15, 1
addi x17, x16, 1
addi x18, x17, 1
addi x19, x18, 1
addi x20, x19, 1
addi x21, x20, 1
addi x22, x21, 1
addi x23, x22, 1
addi x24, x23, 1
addi x25, x24, 1
addi x26, x25, 1
addi x27, x26, 1
addi x28, x27, 1
addi x29, x28, 1
addi x30, x29, 1
addi x31, x30, 1
main_end:
j main_end

View file

@ -0,0 +1,47 @@
#include "init.h"
#include "encoding.h"
int main(void);
trap_handler_t trap_handler[NHARTS] = {0};
void set_trap_handler(trap_handler_t handler)
{
unsigned hartid = read_csr(mhartid);
trap_handler[hartid] = handler;
}
void enable_timer_interrupts()
{
set_csr(mie, MIP_MTIP);
set_csr(mstatus, MSTATUS_MIE);
}
void handle_trap(unsigned int mcause, void *mepc, void *sp)
{
unsigned hartid = read_csr(mhartid);
if (trap_handler[hartid]) {
trap_handler[hartid](hartid, mcause, mepc, sp);
return;
}
while (1)
;
}
void _exit(int status)
{
// Make sure gcc doesn't inline _exit, so we can actually set a breakpoint
// on it.
volatile int i = 42;
while (i)
;
// _exit isn't supposed to return.
while (1)
;
}
void _init()
{
_exit(main());
}

View file

@ -0,0 +1,12 @@
#ifndef INIT_H
#define INIT_H
#define MTIME (*(volatile long long *)(0x02000000 + 0xbff8))
#define MTIMECMP ((volatile long long *)(0x02000000 + 0x4000))
typedef void* (*trap_handler_t)(unsigned hartid, unsigned mcause, void *mepc,
void *sp);
void set_trap_handler(trap_handler_t handler);
void enable_timer_interrupts();
#endif

View file

@ -0,0 +1,35 @@
#include "init.h"
#include "encoding.h"
static volatile unsigned interrupt_count;
static volatile unsigned local;
static volatile unsigned keep_running;
static unsigned delta = 0x100;
void *increment_count(unsigned hartid, unsigned mcause, void *mepc, void *sp)
{
interrupt_count++;
// There is no guarantee that the interrupt is cleared immediately when
// MTIMECMP is written, so stick around here until that happens.
while (read_csr(mip) & MIP_MTIP) {
MTIMECMP[hartid] = MTIME + delta;
}
return mepc;
}
int main()
{
interrupt_count = 0;
local = 0;
keep_running = 1;
unsigned hartid = read_csr(mhartid);
set_trap_handler(increment_count);
MTIMECMP[hartid] = MTIME - 1;
enable_timer_interrupts();
while (keep_running) {
local++;
}
return 10;
}

View file

@ -0,0 +1,46 @@
#include "encoding.h"
#define PGSHIFT 12
.global main
.section .text
main:
# Set up a page table entry that maps 0x0... to 0x8...
la t0, page_table
srli t0, t0, PGSHIFT
csrw CSR_SATP, t0
# update mstatus
csrr t1, CSR_MSTATUS
#if XLEN == 32
li t0, (MSTATUS_MPRV | (SATP_MODE_SV32 << 24))
#else
li t0, (MSTATUS_MPRV | (SATP_MODE_SV39 << 24))
#endif
#li t0, ((VM_SV39 << 24))
or t1, t0, t1
csrw CSR_MSTATUS, t1
la t0, (loop - 0x80000000)
csrw CSR_MEPC, t0
# Exit supervisor mode, entering user mode at loop.
mret
loop:
la t0, data
lw t1, 0(t0)
j loop
.section .data
data:
.word 0xbead
.balign 0x1000
page_table:
#if XLEN == 32
.word ((0x80000000 >> 2) | PTE_V | PTE_R | PTE_W | PTE_X | PTE_G | PTE_U)
#else
.word ((0x80000000 >> 2) | PTE_V | PTE_R | PTE_W | PTE_X | PTE_G | PTE_U)
.word 0
#endif

View file

@ -0,0 +1,89 @@
#include <stdint.h>
#include "init.h"
#include "encoding.h"
typedef struct {
int counter;
} atomic_t;
static inline int atomic_xchg(atomic_t *v, int n)
{
register int c;
__asm__ __volatile__ (
"amoswap.w.aqrl %0, %2, %1"
: "=r" (c), "+A" (v->counter)
: "r" (n));
return c;
}
static inline void mb(void)
{
__asm__ __volatile__ ("fence");
}
void get_lock(atomic_t *lock)
{
while (atomic_xchg(lock, 1) == 1)
;
mb();
}
void put_lock(atomic_t *lock)
{
mb();
atomic_xchg(lock, 0);
}
static atomic_t buf_lock = { .counter = 0 };
static char buf[32];
static int buf_initialized;
static unsigned hart_count[NHARTS];
static unsigned interrupt_count[NHARTS];
static unsigned delta = 0x100;
void *increment_count(unsigned hartid, unsigned mcause, void *mepc, void *sp)
{
interrupt_count[hartid]++;
MTIMECMP[hartid] = MTIME + delta;
return mepc;
}
int main()
{
uint32_t hartid = read_csr(mhartid);
hart_count[hartid] = 0;
interrupt_count[hartid] = 0;
set_trap_handler(increment_count);
// Despite being memory-mapped, there appears to be one mtimecmp
// register per hart. The spec does not address this.
MTIMECMP[hartid] = MTIME + delta;
enable_timer_interrupts();
while (1) {
get_lock(&buf_lock);
if (!buf_initialized) {
for (unsigned i = 0; i < sizeof(buf); i++) {
buf[i] = 'A' + (i % 26);
}
buf_initialized = 1;
}
char first = buf[0];
int offset = (first & ~0x20) - 'A';
for (unsigned i = 0; i < sizeof(buf); i++) {
while (buf[i] != (first - offset + ((offset + i) % 26)))
;
if (hartid & 1)
buf[i] = 'A' + ((i + hartid + hart_count[hartid]) % 26);
else
buf[i] = 'a' + ((i + hartid + hart_count[hartid]) % 26);
}
put_lock(&buf_lock);
hart_count[hartid]++;
}
}

View file

@ -0,0 +1,11 @@
#include "encoding.h"
.global main
.section .text
main:
# MISA is only readable from machine mode
csrr t0, CSR_MISA
csrr t0, CSR_MISA
csrr t0, CSR_MISA
csrr t0, CSR_MISA

View file

@ -0,0 +1,60 @@
#if XLEN == 64
# define LREG ld
# define SREG sd
# define REGBYTES 8
#else
# define LREG lw
# define SREG sw
# define REGBYTES 4
#endif
#include "encoding.h"
.global main
main:
nop
j main
write_regs:
SREG x2, 0(x1)
SREG x3, 8(x1)
SREG x4, 16(x1)
SREG x5, 24(x1)
SREG x6, 32(x1)
SREG x7, 40(x1)
SREG x8, 48(x1)
SREG x9, 56(x1)
SREG x10, 64(x1)
SREG x11, 72(x1)
SREG x12, 80(x1)
SREG x13, 88(x1)
SREG x14, 96(x1)
SREG x15, 104(x1)
#ifndef RV32E
SREG x16, 112(x1)
SREG x17, 120(x1)
SREG x18, 128(x1)
SREG x19, 136(x1)
SREG x20, 144(x1)
SREG x21, 152(x1)
SREG x22, 160(x1)
SREG x23, 168(x1)
SREG x24, 176(x1)
SREG x25, 184(x1)
SREG x26, 192(x1)
SREG x27, 200(x1)
SREG x28, 208(x1)
SREG x29, 216(x1)
SREG x30, 224(x1)
SREG x31, 232(x1)
#endif
csrr x1, CSR_MSCRATCH
all_done:
j all_done
.section .bss
.balign 16
data:
.fill 64, 8, 0

View file

@ -0,0 +1,18 @@
#if XLEN == 64
# define LREG ld
# define SREG sd
# define REGBYTES 8
#else
# define LREG lw
# define SREG sw
# define REGBYTES 4
#endif
.global main
main:
li s0, 0
li s1, 0x0200bff8
loop:
addi s0, s0, 1
LREG s2, 0(s1)
j loop

View file

@ -0,0 +1,77 @@
#include <stdint.h>
#include "semihosting.h"
size_t strlen(const char *buf)
{
int len = 0;
while (buf[len])
len++;
return len;
}
#define O_RDONLY 0
#define O_WRONLY 1
#define O_RDWR 2
#define O_RDWR 2
#define O_TRUNC 0x0800
int errno;
/* These semihosting functions came from the Freedom Metal source. */
static int open(const char *name, int flags, int mode) {
int semiflags = 0;
switch (flags & (O_RDONLY | O_WRONLY | O_RDWR)) {
case O_RDONLY:
semiflags = 0; /* 'r' */
break;
case O_WRONLY:
if (flags & O_TRUNC)
semiflags = 4; /* 'w' */
else
semiflags = 8; /* 'a' */
break;
default:
if (flags & O_TRUNC)
semiflags = 6; /* 'w+' */
else
semiflags = 10; /* 'a+' */
break;
}
volatile semihostparam_t arg = {.param1 = (uintptr_t)name,
.param2 = (uintptr_t)semiflags,
.param3 = (uintptr_t)strlen(name)};
int ret = (int)semihost_call_host(SEMIHOST_SYS_OPEN, (uintptr_t)&arg);
if (ret == -1)
errno = semihost_call_host(SEMIHOST_SYS_ERRNO, 0);
return ret;
}
static ssize_t write(int file, const void *ptr, size_t len)
{
volatile semihostparam_t arg = {.param1 = (uintptr_t)file,
.param2 = (uintptr_t)ptr,
.param3 = (uintptr_t)len};
ssize_t ret =
(ssize_t)semihost_call_host(SEMIHOST_SYS_WRITE, (uintptr_t)&arg);
return (len - ret);
}
int main()
{
char *filename = NULL;
const char *message = "Hello, world!\n";
const char *message2 = "Do re mi fa so la ti do!\n";
int fd;
begin:
fd = open(filename, O_WRONLY, 0644);
write(fd, message, strlen(message));
write(1, message2, strlen(message2));
return 10;
}

View file

@ -0,0 +1,82 @@
#include <sys/types.h>
#ifndef _SEMIHOSTING_H_
#define _SEMIHOSTING_H_
// ----------------------------------------------------------------------------
// Semihosting operations.
enum Semihost_Sys_Op {
// Regular operations
SEMIHOST_SYS_CLOCK = 0x10,
SEMIHOST_SYS_CLOSE = 0x02,
SEMIHOST_SYS_ELAPSED = 0x30,
SEMIHOST_SYS_ERRNO = 0x13,
SEMIHOST_SYS_EXIT = 0x18,
SEMIHOST_SYS_EXIT_EXTENDED = 0x20,
SEMIHOST_SYS_FLEN = 0x0C,
SEMIHOST_SYS_GET_CMDLINE = 0x15,
SEMIHOST_SYS_HEAPINFO = 0x16,
SEMIHOST_SYS_ISERROR = 0x08,
SEMIHOST_SYS_ISTTY = 0x09,
SEMIHOST_SYS_OPEN = 0x01,
SEMIHOST_SYS_READ = 0x06,
SEMIHOST_SYS_READC = 0x07,
SEMIHOST_SYS_REMOVE = 0x0E,
SEMIHOST_SYS_RENAME = 0x0F,
SEMIHOST_SYS_SEEK = 0x0A,
SEMIHOST_SYS_SYSTEM = 0x12,
SEMIHOST_SYS_TICKFREQ = 0x31,
SEMIHOST_SYS_TIME = 0x11,
SEMIHOST_SYS_TMPNAM = 0x0D,
SEMIHOST_SYS_WRITE = 0x05,
SEMIHOST_SYS_WRITEC = 0x03,
SEMIHOST_SYS_WRITE0 = 0x04,
};
enum ADP_Code {
ADP_Stopped_BranchThroughZero = 0x20000,
ADP_Stopped_UndefinedInstr = 0x20001,
ADP_Stopped_SoftwareInterrupt = 0x20002,
ADP_Stopped_PrefetchAbort = 0x20003,
ADP_Stopped_DataAbort = 0x20004,
ADP_Stopped_AddressException = 0x20005,
ADP_Stopped_IRQ = 0x20006,
ADP_Stopped_FIQ = 0x20007,
ADP_Stopped_BreakPoint = 0x20020,
ADP_Stopped_WatchPoint = 0x20021,
ADP_Stopped_StepComplete = 0x20022,
ADP_Stopped_RunTimeErrorUnknown = 0x20023,
ADP_Stopped_InternalError = 0x20024,
ADP_Stopped_UserInterruption = 0x20025,
ADP_Stopped_ApplicationExit = 0x20026,
ADP_Stopped_StackOverflow = 0x20027,
ADP_Stopped_DivisionByZero = 0x20028,
ADP_Stopped_OSSpecific = 0x20029,
};
typedef struct {
uintptr_t param1;
uintptr_t param2;
uintptr_t param3;
} semihostparam_t;
static inline uintptr_t __attribute__((always_inline))
semihost_call_host(uintptr_t op, uintptr_t arg) {
register uintptr_t r0 asm("a0") = op;
register uintptr_t r1 asm("a1") = arg;
asm volatile(".option push \n"
".option norvc \n"
" slli zero,zero,0x1f \n"
" ebreak \n"
" srai zero,zero,0x7 \n"
".option pop \n"
: "=r"(r0) /* Outputs */
: "r"(r0), "r"(r1) /* Inputs */
: "memory");
return r0;
}
#endif

View file

@ -0,0 +1,28 @@
// Test stepping over a variety of instructions.
.global main
main:
la t0, trap_entry // 0, 4
csrw mtvec, t0 // 0x8
li t0, 5 // 0xc
beq zero, zero, one // 0x10
nop // 0x14
one:
beq zero, t0, one // 0x18
// Use t0 instead of ra to force a 32-bit opcode in C mode. Otherwise
// 32-bit and 64-bit binaries end up with different instructions (I
// didn't pursue this).
jal t0, two // 0x1c
three:
.word 0 // 0x20
nop // 0x24
two:
jr t0 // 0x28
.align 2
trap_entry:
j trap_entry // 0x2c

View file

@ -0,0 +1,600 @@
// https://github.com/32bitmicro/newlib-nano-1.0/blob/master/newlib/libc/machine/xstormy16/tiny-malloc.c
/* A replacement malloc with:
- Much reduced code size;
- Smaller RAM footprint;
- The ability to handle downward-growing heaps;
but
- Slower;
- Probably higher memory fragmentation;
- Doesn't support threads (but, if it did support threads,
it wouldn't need a global lock, only a compare-and-swap instruction);
- Assumes the maximum alignment required is the alignment of a pointer;
- Assumes that memory is already there and doesn't need to be allocated.
* Synopsis of public routines
malloc(size_t n);
Return a pointer to a newly allocated chunk of at least n bytes, or null
if no space is available.
free(void* p);
Release the chunk of memory pointed to by p, or no effect if p is null.
realloc(void* p, size_t n);
Return a pointer to a chunk of size n that contains the same data
as does chunk p up to the minimum of (n, p's size) bytes, or null
if no space is available. The returned pointer may or may not be
the same as p. If p is null, equivalent to malloc. Unless the
#define REALLOC_ZERO_BYTES_FREES below is set, realloc with a
size argument of zero (re)allocates a minimum-sized chunk.
memalign(size_t alignment, size_t n);
Return a pointer to a newly allocated chunk of n bytes, aligned
in accord with the alignment argument, which must be a power of
two. Will fail if 'alignment' is too large.
calloc(size_t unit, size_t quantity);
Returns a pointer to quantity * unit bytes, with all locations
set to zero.
cfree(void* p);
Equivalent to free(p).
malloc_trim(size_t pad);
Release all but pad bytes of freed top-most memory back
to the system. Return 1 if successful, else 0.
malloc_usable_size(void* p);
Report the number usable allocated bytes associated with allocated
chunk p. This may or may not report more bytes than were requested,
due to alignment and minimum size constraints.
malloc_stats();
Prints brief summary statistics on stderr.
mallinfo()
Returns (by copy) a struct containing various summary statistics.
mallopt(int parameter_number, int parameter_value)
Changes one of the tunable parameters described below. Returns
1 if successful in changing the parameter, else 0. Actually, returns 0
always, as no parameter can be changed.
*/
#ifdef __xstormy16__
#define MALLOC_DIRECTION -1
#endif
#ifndef MALLOC_DIRECTION
#define MALLOC_DIRECTION 1
#endif
#include <stddef.h>
void* malloc(size_t);
void free(void*);
void* realloc(void*, size_t);
void* memalign(size_t, size_t);
void* valloc(size_t);
void* pvalloc(size_t);
void* calloc(size_t, size_t);
void cfree(void*);
int malloc_trim(size_t);
size_t malloc_usable_size(void*);
void malloc_stats(void);
int mallopt(int, int);
struct mallinfo mallinfo(void);
typedef struct freelist_entry {
size_t size;
struct freelist_entry *next;
} *fle;
extern void * __malloc_end;
extern fle __malloc_freelist;
/* Return the number of bytes that need to be added to X to make it
aligned to an ALIGN boundary. ALIGN must be a power of 2. */
#define M_ALIGN(x, align) (-(size_t)(x) & ((align) - 1))
/* Return the number of bytes that need to be subtracted from X to make it
aligned to an ALIGN boundary. ALIGN must be a power of 2. */
#define M_ALIGN_SUB(x, align) ((size_t)(x) & ((align) - 1))
extern char *__malloc_start;
/* This is the minimum gap allowed between __malloc_end and the top of
the stack. This is only checked for when __malloc_end is
decreased; if instead the stack grows into the heap, silent data
corruption will result. */
#define MALLOC_MINIMUM_GAP 32
#ifdef __xstormy16__
register void * stack_pointer asm ("r15");
#define MALLOC_LIMIT stack_pointer
#else
#define MALLOC_LIMIT __builtin_frame_address (0)
#endif
#if MALLOC_DIRECTION < 0
#define CAN_ALLOC_P(required) \
(((size_t) __malloc_end - (size_t)MALLOC_LIMIT \
- MALLOC_MINIMUM_GAP) >= (required))
#else
#define CAN_ALLOC_P(required) \
(((size_t)MALLOC_LIMIT - (size_t) __malloc_end \
- MALLOC_MINIMUM_GAP) >= (required))
#endif
/* real_size is the size we actually have to allocate, allowing for
overhead and alignment. */
#define REAL_SIZE(sz) \
((sz) < sizeof (struct freelist_entry) - sizeof (size_t) \
? sizeof (struct freelist_entry) \
: sz + sizeof (size_t) + M_ALIGN(sz, sizeof (size_t)))
#ifdef DEFINE_MALLOC
void * __malloc_end = &__malloc_start;
fle __malloc_freelist;
void *
malloc (size_t sz)
{
fle *nextfree;
fle block;
/* real_size is the size we actually have to allocate, allowing for
overhead and alignment. */
size_t real_size = REAL_SIZE (sz);
/* Look for the first block on the freelist that is large enough. */
for (nextfree = &__malloc_freelist;
*nextfree;
nextfree = &(*nextfree)->next)
{
block = *nextfree;
if (block->size >= real_size)
{
/* If the block found is just the right size, remove it from
the free list. Otherwise, split it. */
if (block->size < real_size + sizeof (struct freelist_entry))
{
*nextfree = block->next;
return (void *)&block->next;
}
else
{
size_t newsize = block->size - real_size;
fle newnext = block->next;
*nextfree = (fle)((size_t)block + real_size);
(*nextfree)->size = newsize;
(*nextfree)->next = newnext;
goto done;
}
}
/* If this is the last block on the freelist, and it was too small,
enlarge it. */
if (! block->next
&& __malloc_end == (void *)((size_t)block + block->size))
{
size_t moresize = real_size - block->size;
if (! CAN_ALLOC_P (moresize))
return NULL;
*nextfree = NULL;
if (MALLOC_DIRECTION < 0)
{
block = __malloc_end = (void *)((size_t)block - moresize);
}
else
{
__malloc_end = (void *)((size_t)block + real_size);
}
goto done;
}
}
/* No free space at the end of the free list. Allocate new space
and use that. */
if (! CAN_ALLOC_P (real_size))
return NULL;
if (MALLOC_DIRECTION > 0)
{
block = __malloc_end;
__malloc_end = (void *)((size_t)__malloc_end + real_size);
}
else
{
block = __malloc_end = (void *)((size_t)__malloc_end - real_size);
}
done:
block->size = real_size;
return (void *)&block->next;
}
#endif
#ifdef DEFINE_FREE
void
free (void *block_p)
{
fle *nextfree;
fle block = (fle)((size_t) block_p - offsetof (struct freelist_entry, next));
if (block_p == NULL)
return;
/* Look on the freelist to see if there's a free block just before
or just after this block. */
for (nextfree = &__malloc_freelist;
*nextfree;
nextfree = &(*nextfree)->next)
{
fle thisblock = *nextfree;
if ((size_t)thisblock + thisblock->size == (size_t) block)
{
thisblock->size += block->size;
if (MALLOC_DIRECTION > 0
&& thisblock->next
&& (size_t) block + block->size == (size_t) thisblock->next)
{
thisblock->size += thisblock->next->size;
thisblock->next = thisblock->next->next;
}
return;
}
else if ((size_t) thisblock == (size_t) block + block->size)
{
if (MALLOC_DIRECTION < 0
&& thisblock->next
&& (size_t) block == ((size_t) thisblock->next
+ thisblock->next->size))
{
*nextfree = thisblock->next;
thisblock->next->size += block->size + thisblock->size;
}
else
{
block->size += thisblock->size;
block->next = thisblock->next;
*nextfree = block;
}
return;
}
else if ((MALLOC_DIRECTION > 0
&& (size_t) thisblock > (size_t) block)
|| (MALLOC_DIRECTION < 0
&& (size_t) thisblock < (size_t) block))
break;
}
block->next = *nextfree;
*nextfree = block;
return;
}
#endif
#ifdef DEFINE_REALLOC
void *
realloc (void *block_p, size_t sz)
{
fle block = (fle)((size_t) block_p - offsetof (struct freelist_entry, next));
size_t real_size = REAL_SIZE (sz);
size_t old_real_size;
if (block_p == NULL)
return malloc (sz);
old_real_size = block->size;
/* Perhaps we need to allocate more space. */
if (old_real_size < real_size)
{
void *result;
size_t old_size = old_real_size - sizeof (size_t);
/* Need to allocate, copy, and free. */
result = malloc (sz);
if (result == NULL)
return NULL;
memcpy (result, block_p, old_size < sz ? old_size : sz);
free (block_p);
return result;
}
/* Perhaps we can free some space. */
if (old_real_size - real_size >= sizeof (struct freelist_entry))
{
fle newblock = (fle)((size_t)block + real_size);
block->size = real_size;
newblock->size = old_real_size - real_size;
free (&newblock->next);
}
return block_p;
}
#endif
#ifdef DEFINE_CALLOC
void *
calloc (size_t n, size_t elem_size)
{
void *result;
size_t sz = n * elem_size;
result = malloc (sz);
if (result != NULL)
memset (result, 0, sz);
return result;
}
#endif
#ifdef DEFINE_CFREE
void
cfree (void *p)
{
free (p);
}
#endif
#ifdef DEFINE_MEMALIGN
void *
memalign (size_t align, size_t sz)
{
fle *nextfree;
fle block;
/* real_size is the size we actually have to allocate, allowing for
overhead and alignment. */
size_t real_size = REAL_SIZE (sz);
/* Some sanity checking on 'align'. */
if ((align & (align - 1)) != 0
|| align <= 0)
return NULL;
/* Look for the first block on the freelist that is large enough. */
/* One tricky part is this: We want the result to be a valid pointer
to free. That means that there has to be room for a size_t
before the block. If there's additional space before the block,
it should go on the freelist, or it'll be lost---we could add it
to the size of the block before it in memory, but finding the
previous block is expensive. */
for (nextfree = &__malloc_freelist;
;
nextfree = &(*nextfree)->next)
{
size_t before_size;
size_t old_size;
/* If we've run out of free blocks, allocate more space. */
if (! *nextfree)
{
old_size = real_size;
if (MALLOC_DIRECTION < 0)
{
old_size += M_ALIGN_SUB (((size_t)__malloc_end
- old_size + sizeof (size_t)),
align);
if (! CAN_ALLOC_P (old_size))
return NULL;
block = __malloc_end = (void *)((size_t)__malloc_end - old_size);
}
else
{
block = __malloc_end;
old_size += M_ALIGN ((size_t)__malloc_end + sizeof (size_t),
align);
if (! CAN_ALLOC_P (old_size))
return NULL;
__malloc_end = (void *)((size_t)__malloc_end + old_size);
}
*nextfree = block;
block->size = old_size;
block->next = NULL;
}
else
{
block = *nextfree;
old_size = block->size;
}
before_size = M_ALIGN (&block->next, align);
if (before_size != 0)
before_size = sizeof (*block) + M_ALIGN (&(block+1)->next, align);
/* If this is the last block on the freelist, and it is too small,
enlarge it. */
if (! block->next
&& old_size < real_size + before_size
&& __malloc_end == (void *)((size_t)block + block->size))
{
if (MALLOC_DIRECTION < 0)
{
size_t moresize = real_size - block->size;
moresize += M_ALIGN_SUB ((size_t)&block->next - moresize, align);
if (! CAN_ALLOC_P (moresize))
return NULL;
block = __malloc_end = (void *)((size_t)block - moresize);
block->next = NULL;
block->size = old_size = old_size + moresize;
before_size = 0;
}
else
{
if (! CAN_ALLOC_P (before_size + real_size - block->size))
return NULL;
__malloc_end = (void *)((size_t)block + before_size + real_size);
block->size = old_size = before_size + real_size;
}
/* Two out of the four cases below will now be possible; which
two depends on MALLOC_DIRECTION. */
}
if (old_size >= real_size + before_size)
{
/* This block will do. If there needs to be space before it,
split the block. */
if (before_size != 0)
{
fle old_block = block;
old_block->size = before_size;
block = (fle)((size_t)block + before_size);
/* If there's no space after the block, we're now nearly
done; just make a note of the size required.
Otherwise, we need to create a new free space block. */
if (old_size - before_size
<= real_size + sizeof (struct freelist_entry))
{
block->size = old_size - before_size;
return (void *)&block->next;
}
else
{
fle new_block;
new_block = (fle)((size_t)block + real_size);
new_block->size = old_size - before_size - real_size;
if (MALLOC_DIRECTION > 0)
{
new_block->next = old_block->next;
old_block->next = new_block;
}
else
{
new_block->next = old_block;
*nextfree = new_block;
}
goto done;
}
}
else
{
/* If the block found is just the right size, remove it from
the free list. Otherwise, split it. */
if (old_size <= real_size + sizeof (struct freelist_entry))
{
*nextfree = block->next;
return (void *)&block->next;
}
else
{
size_t newsize = old_size - real_size;
fle newnext = block->next;
*nextfree = (fle)((size_t)block + real_size);
(*nextfree)->size = newsize;
(*nextfree)->next = newnext;
goto done;
}
}
}
}
done:
block->size = real_size;
return (void *)&block->next;
}
#endif
#ifdef DEFINE_VALLOC
void *
valloc (size_t sz)
{
return memalign (128, sz);
}
#endif
#ifdef DEFINE_PVALLOC
void *
pvalloc (size_t sz)
{
return memalign (128, sz + M_ALIGN (sz, 128));
}
#endif
#ifdef DEFINE_MALLINFO
#include "malloc.h"
struct mallinfo
mallinfo (void)
{
struct mallinfo r;
fle fr;
size_t free_size;
size_t total_size;
size_t free_blocks;
memset (&r, 0, sizeof (r));
free_size = 0;
free_blocks = 0;
for (fr = __malloc_freelist; fr; fr = fr->next)
{
free_size += fr->size;
free_blocks++;
if (! fr->next)
{
int atend;
if (MALLOC_DIRECTION > 0)
atend = (void *)((size_t)fr + fr->size) == __malloc_end;
else
atend = (void *)fr == __malloc_end;
if (atend)
r.keepcost = fr->size;
}
}
if (MALLOC_DIRECTION > 0)
total_size = (char *)__malloc_end - (char *)&__malloc_start;
else
total_size = (char *)&__malloc_start - (char *)__malloc_end;
#ifdef DEBUG
/* Fixme: should walk through all the in-use blocks and see if
they're valid. */
#endif
r.arena = total_size;
r.fordblks = free_size;
r.uordblks = total_size - free_size;
r.ordblks = free_blocks;
return r;
}
#endif
#ifdef DEFINE_MALLOC_STATS
#include "malloc.h"
#include <stdio.h>
void
malloc_stats(void)
{
struct mallinfo i;
FILE *fp;
fp = stderr;
i = mallinfo();
fprintf (fp, "malloc has reserved %u bytes between %p and %p\n",
i.arena, &__malloc_start, __malloc_end);
fprintf (fp, "there are %u bytes free in %u chunks\n",
i.fordblks, i.ordblks);
fprintf (fp, "of which %u bytes are at the end of the reserved space\n",
i.keepcost);
fprintf (fp, "and %u bytes are in use.\n", i.uordblks);
}
#endif
#ifdef DEFINE_MALLOC_USABLE_SIZE
size_t
malloc_usable_size (void *block_p)
{
fle block = (fle)((size_t) block_p - offsetof (struct freelist_entry, next));
return block->size - sizeof (size_t);
}
#endif
#ifdef DEFINE_MALLOPT
int
mallopt (int n, int v)
{
(void)n; (void)v;
return 0;
}
#endif

View file

@ -0,0 +1,190 @@
#include <stdint.h>
#include "encoding.h"
#define get_field(reg, mask) (((reg) & (mask)) / ((mask) & ~((mask) << 1)))
#define set_field(reg, mask, val) (((reg) & ~(mask)) | (((val) * ((mask) & ~((mask) << 1))) & (mask)))
#if __riscv_xlen == 64
# define SATP_PPN SATP64_PPN
typedef uint64_t reg_t;
#else
# define SATP_PPN SATP32_PPN
typedef uint32_t reg_t;
#endif
static char page_buffer[4096 * 6];
static char *page_buffer_next = page_buffer;
typedef struct {
unsigned mode;
unsigned levels;
unsigned ppn_width_bits[5];
unsigned ppn_offset_bits[5];
unsigned entry_width_bytes;
unsigned vpn_width_bits;
unsigned vaddr_bits;
} virtual_memory_system_t;
static virtual_memory_system_t sv32 = {
.mode = SATP_MODE_SV32,
.levels = 2,
.ppn_width_bits = {12, 10, 10},
.ppn_offset_bits = {0, 12, 22},
.entry_width_bytes = 4,
.vpn_width_bits = 10,
.vaddr_bits = 32
};
static virtual_memory_system_t sv39 = {
.mode = SATP_MODE_SV39,
.levels = 3,
.ppn_width_bits = {12, 9, 9, 26},
.ppn_offset_bits = {0, 12, 21, 30},
.entry_width_bytes = 8,
.vpn_width_bits = 9,
.vaddr_bits = 39
};
static virtual_memory_system_t sv48 = {
.mode = SATP_MODE_SV48,
.levels = 4,
.ppn_width_bits = {12, 9, 9, 9, 26},
.ppn_offset_bits = {0, 12, 21, 30, 39},
.entry_width_bytes = 8,
.vpn_width_bits = 9,
.vaddr_bits = 48
};
static virtual_memory_system_t *vms;
void error()
{
while (1)
;
}
void assert(int condition)
{
if (!condition)
error();
}
// Return a 4Kb, aligned, page.
void *get_page()
{
page_buffer_next = (char *) (((unsigned long) page_buffer_next + 4095) & ~0xfff);
while (page_buffer_next + 4096 >= page_buffer + sizeof(page_buffer))
;
void *result = page_buffer_next;
page_buffer_next += 4096;
return result;
}
reg_t entry(char *table, unsigned index)
{
if (vms->entry_width_bytes == 4)
return ((uint32_t *) table)[index];
else if (vms->entry_width_bytes == 8)
return ((uint64_t *) table)[index];
else
assert(0);
}
void entry_set(char *table, unsigned index, uint64_t value)
{
if (vms->entry_width_bytes == 4)
((uint32_t *) table)[index] = value;
else if (vms->entry_width_bytes == 8)
((uint64_t *) table)[index] = value;
else
assert(0);
}
// Set up 1-to-1 for this entire table.
void setup_page_table(char *table, unsigned level, uint64_t physical)
{
for (unsigned i = 0; i < (1<<vms->vpn_width_bits); i++) {
uint64_t pte = PTE_V | PTE_R | PTE_W | PTE_X | PTE_U | PTE_A | PTE_D;
// Add in portion of physical address.
pte |= physical & (((1LL<<vms->vpn_width_bits)-1) <<
(PTE_PPN_SHIFT + (level+1) * vms->vpn_width_bits));
// Add in the index.
pte |= ((reg_t) i) << (PTE_PPN_SHIFT + level * vms->vpn_width_bits);
entry_set(table, i, pte);
}
}
// Return contents of vpn field for the given virtual address and level.
unsigned vpn(uint64_t virtual, unsigned level)
{
virtual >>= 12 + vms->vpn_width_bits * level;
return virtual & ((1<<vms->vpn_width_bits)-1);
}
// Add an entry to the given table, at the given level (0 for 4Kb page).
void add_entry(char *table, unsigned level, uint64_t virtual, uint64_t physical)
{
unsigned current_level = vms->levels - 1;
while (1) {
unsigned index = vpn(virtual, current_level);
if (current_level <= level) {
// Add the new entry.
entry_set(table, index, PTE_V | PTE_R | PTE_W | PTE_X | PTE_U | PTE_A | PTE_D |
((physical >> 2) & ~((1 <<
(PTE_PPN_SHIFT + current_level * vms->vpn_width_bits)) - 1)));
return;
}
reg_t pte = entry(table, index);
if (!(pte & PTE_V) ||
((pte & PTE_R) && (pte & PTE_W))) {
// Create a new page
void *new_page = get_page();
setup_page_table(new_page, current_level - 1, virtual);
entry_set(table, index, PTE_V |
((((reg_t) new_page) >> 2) & ~((1 << 10) - 1)));
table = new_page;
} else {
table = (char *) (pte & ~0xfff);
}
current_level--;
}
}
int main()
{
void *master_table = get_page();
setup_page_table(master_table, vms->levels-1, 0);
uint32_t *physical = get_page();
//uint32_t *virtual = (uint32_t *) (((reg_t) physical) ^ ((reg_t) 0x40000000));
uint32_t *virtual = (uint32_t *) (((reg_t) physical) ^ (((reg_t) 0xf) << (vms->vaddr_bits - 4)));
// Virtual addresses must be sign-extended.
if (vms->vaddr_bits < sizeof(virtual) * 8 && (reg_t) virtual & ((reg_t) 1<<(vms->vaddr_bits-1)))
virtual = (uint32_t *) (
(reg_t) virtual | ~(((reg_t) 1 << vms->vaddr_bits) - 1));
add_entry(master_table, 0, (reg_t) virtual, (reg_t) physical);
unsigned long satp = set_field(0, SATP_MODE, vms->mode);
satp = set_field(satp, SATP_PPN, ((unsigned long) master_table) >> 12);
write_csr(satp, satp);
satp = read_csr(satp);
if (get_field(satp, SATP_MODE) != vms->mode)
error();
reg_t mstatus = read_csr(mstatus);
mstatus |= MSTATUS_MPRV;
write_csr(mstatus, mstatus);
// Address translation is enabled.
physical[0] = 0xdeadbeef;
virtual[1] = 0x55667788;
assert(virtual[0] == 0xdeadbeef);
assert(physical[0] == 0xdeadbeef);
assert(virtual[1] == 0x55667788);
assert(physical[1] == 0x55667788);
active:
end:
while (1)
;
}

View file

@ -0,0 +1,114 @@
#include "encoding.h"
#if XLEN == 64
# define LREG ld
# define SREG sd
# define REGBYTES 8
#else
# define LREG lw
# define SREG sw
# define REGBYTES 4
#endif
.global main
.section .text
main:
la a0, data
li t0, 0
just_before_read_loop:
li t2, 16
read_loop:
lw t1, 0(a0)
addi t1, t1, 1
addi t0, t0, 1
read_again:
lw t1, 0(a0)
addi a0, a0, 4
blt t0, t2, read_loop
la a0, data
just_before_write_loop:
li t0, 1
write_loop:
sw t0, 0(a0)
addi t0, t0, 1
addi a0, a0, 4
blt t0, t2, write_loop
j main_exit
write_store_trigger:
/* 2<<60 is for RV64. 2<<28 is for RV32. That's safe because on RV64 bits 28 and 29 are 0. */
li a0, (2<<60) | (2<<28) | (1<<6) | (1<<1)
li a1, 0xdeadbee0
jal write_triggers
la a0, data
jal read_triggers
write_load_trigger:
li a0, (2<<60) | (2<<28) | (1<<6) | (1<<0)
li a1, 0xfeedac00
jal write_triggers
la a0, data
jal read_triggers
// Clear triggers so the next test can use them.
clear_triggers:
li a0, 0
jal write_triggers
main_exit:
li a0, 10
j _exit
write_triggers:
// a0: value to write to each tdata1
// a1: value to write to each tdata2
li t0, 0
2:
csrw CSR_TSELECT, t0
csrr t1, CSR_TSELECT
bne t0, t1, 1f
addi t0, t0, 1
csrw CSR_TDATA2, a1
csrw CSR_TDATA1, a0
j 2b
1: ret
read_triggers:
// a0: address where data should be written
li t0, 0
2:
csrw CSR_TSELECT, t0
csrr t1, CSR_TSELECT
bne t0, t1, 1f
addi t0, t0, 1
csrr t1, CSR_TDATA1
SREG t1, 0(a0)
csrr t1, CSR_TDATA2
SREG t1, REGBYTES(a0)
addi a0, a0, 2*REGBYTES
j 2b
1: SREG zero, 0(a0)
ret
.section .data
.align 3
data: .word 0x40
.word 0x41
.word 0x42
.word 0x43
.word 0x44
.word 0x45
.word 0x46
.word 0x47
.word 0x48
.word 0x49
.word 0x4a
.word 0x4b
.word 0x4c
.word 0x4d
.word 0x4e
.word 0x4f

View file

@ -0,0 +1,159 @@
#include "encoding.h"
#if XLEN == 64
# define LREG ld
# define SREG sd
# define REGBYTES 8
#else
# define LREG lw
# define SREG sw
# define REGBYTES 4
#endif
#define get_field(reg, mask) (((reg) & (mask)) / ((mask) & ~((mask) << 1)))
#define set_field(reg, mask, val) (((reg) & ~(mask)) | (((val) * ((mask) & ~((mask) << 1))) & (mask)))
.global main
.global main_end
.global main_post_csrr
// Load constants into all registers so we can test no register are
// clobbered after attaching.
main:
SREG ra, 0(sp)
addi sp, sp, REGBYTES
// Set VS=1
csrr t0, CSR_MSTATUS
li t1, set_field(0, MSTATUS_VS, 1)
or t0, t0, t1
csrw CSR_MSTATUS, t0
// copy a to b
la a0, a
jal vector_load_v4
la a0, b
jal shift_store_v4
// assert a == b
la a0, a
la a1, b
jal check_equal
test0:
bne a0, zero, return_from_main
// copy b to c
la a0, b
jal shift_load_v4
la a0, c
jal vector_store_v4
// assert b == c
la a0, b
la a1, c
jal check_equal
test1:
bne a0, zero, return_from_main
return_from_main:
addi sp, sp, -REGBYTES
LREG ra, 0(sp)
ret
vector_load_v4:
// a0: point to memory to load from
csrr s0, vlenb
vsetvli zero, s0, e8, m1 # Vectors of 8b
vle8.v v4, 0(a0) # Load bytes
ret
vector_store_v4:
// a0: point to memory to store to
csrr s0, vlenb
vsetvli zero, s0, e8, m1 # Vectors of 8b
vse8.v v4, 0(a0) # Load bytes
ret
shift_load_v4:
// a0: pointer to memory to load from
// Configure all elements in the chain
csrr s0, vlenb
#if XLEN == 32
vsetvli zero, s0, e32
#else
vsetvli zero, s0, e64
#endif
// Figure out how long the chain is.
csrr s0, vlenb
li s1, XLEN/8
divu s0, s0, s1
1:
LREG s2, 0(a0)
vslide1down.vx v4, v4, s2
addi a0, a0, REGBYTES
addi s0, s0, -1
bne s0, zero, 1b
ret
shift_store_v4:
// a0: pointer to memory to store to
// Configure all elements in the chain
csrr s0, vlenb
#if XLEN == 32
vsetvli zero, s0, e32
#else
vsetvli zero, s0, e64
#endif
// Figure out how long the chain is.
csrr s0, vlenb
li s1, XLEN/8
divu s0, s0, s1
1:
vmv.x.s s2, v4
SREG s2, 0(a0)
vslide1down.vx v4, v4, s2
addi a0, a0, REGBYTES
addi s0, s0, -1
bne s0, zero, 1b
ret
check_equal:
csrr s0, vlenb
1:
lb s1, 0(a0)
lb s2, 0(a1)
bne s1, s2, 2f
addi a0, a0, 1
addi a1, a1, 1
addi s0, s0, -1
bne s0, zero, 1b
li a0, 0 // equal
ret
2: // unequal
li a0, 1
ret
.data
.align 6
a: .word 0xaa00, 0xaa01, 0xaa02, 0xaa03, 0xaa04, 0xaa05, 0xaa06, 0xaa07
.word 0xaa08, 0xaa09, 0xaa0a, 0xaa0b, 0xaa0c, 0xaa0d, 0xaa0e, 0xaa0f
.word 0xaa10, 0xaa11, 0xaa12, 0xaa13, 0xaa14, 0xaa15, 0xaa16, 0xaa17
.word 0xaa18, 0xaa19, 0xaa1a, 0xaa1b, 0xaa1c, 0xaa1d, 0xaa1e, 0xaa1f
b: .word 0xbb00, 0xbb01, 0xbb02, 0xbb03, 0xbb04, 0xbb05, 0xbb06, 0xbb07
.word 0xbb08, 0xbb09, 0xbb0b, 0xbb0b, 0xbb0c, 0xbb0d, 0xbb0e, 0xbb0f
.word 0xbb10, 0xbb11, 0xbb13, 0xbb13, 0xbb14, 0xbb15, 0xbb16, 0xbb17
.word 0xbb18, 0xbb19, 0xbb1b, 0xbb1b, 0xbb1c, 0xbb1d, 0xbb1e, 0xbb1f
c: .word 0xcc00, 0xcc01, 0xcc02, 0xcc03, 0xcc04, 0xcc05, 0xcc06, 0xcc07
.word 0xcc08, 0xcc09, 0xcc0c, 0xcc0c, 0xcc0c, 0xcc0d, 0xcc0e, 0xcc0f
.word 0xcc10, 0xcc11, 0xcc13, 0xcc13, 0xcc14, 0xcc15, 0xcc16, 0xcc17
.word 0xcc18, 0xcc19, 0xcc1c, 0xcc1c, 0xcc1c, 0xcc1d, 0xcc1e, 0xcc1f

341
vendor/riscv-tests/debug/pylint.rc vendored Normal file
View file

@ -0,0 +1,341 @@
[MASTER]
# Specify a configuration file.
#rcfile=
# Python code to execute, usually for sys.path manipulation such as
# pygtk.require().
#init-hook=
# Profiled execution.
profile=no
# Add files or directories to the blacklist. They should be base names, not
# paths.
ignore=.git
# Pickle collected data for later comparisons.
persistent=yes
# List of plugins (as comma separated values of python modules names) to load,
# usually to register additional checkers.
load-plugins=
# Allow loading of arbitrary C extensions. Extensions are imported into the
# active Python interpreter and may run arbitrary code.
unsafe-load-any-extension=no
# A comma-separated list of package or module names from where C extensions may
# be loaded. Extensions are loading into the active Python interpreter and may
# run arbitrary code
extension-pkg-whitelist=
[MESSAGES CONTROL]
# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option
# multiple time. See also the "--disable" option for examples.
#enable=
# Disable the message, report, category or checker with the given id(s). You
# can either give multiple identifiers separated by comma (,) or put this
# option multiple times (only on the command line, not in the configuration
# file where it should appear only once).You can also use "--disable=all" to
# disable everything first and then reenable specific checks. For example, if
# you want to run only the similarities checker, you can use "--disable=all
# --enable=similarities". If you want to run only the classes checker, but have
# no Warning level messages displayed, use"--disable=all --enable=classes
# --disable=W"
disable=bad-continuation, missing-docstring, invalid-name, locally-disabled,
too-few-public-methods, too-many-arguments, fixme, duplicate-code,
no-else-return
[REPORTS]
# Set the output format. Available formats are text, parseable, colorized, msvs
# (visual studio) and html. You can also give a reporter class, eg
# mypackage.mymodule.MyReporterClass.
output-format=text
# Put messages in a separate file for each module / package specified on the
# command line instead of printing them on stdout. Reports (if any) will be
# written in a file name "pylint_global.[txt|html]".
files-output=no
# Tells whether to display a full report or only the messages
reports=no
# Python expression which should return a note less than 10 (10 is the highest
# note). You have access to the variables errors warning, statement which
# respectively contain the number of errors / warnings messages and the total
# number of statements analyzed. This is used by the global evaluation report
# (RP0004).
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
# Add a comment according to your evaluation note. This is used by the global
# evaluation report (RP0004).
comment=no
# Template used to display messages. This is a python new-style format string
# used to format the message information. See doc for all details
#msg-template=
[MISCELLANEOUS]
# List of note tags to take in consideration, separated by a comma.
notes=FIXME,XXX,TODO
[SIMILARITIES]
# Minimum lines number of a similarity.
min-similarity-lines=4
# Ignore comments when computing similarities.
ignore-comments=yes
# Ignore docstrings when computing similarities.
ignore-docstrings=yes
# Ignore imports when computing similarities.
ignore-imports=no
[VARIABLES]
# Tells whether we should check for unused import in __init__ files.
init-import=no
# A regular expression matching the name of dummy variables (i.e. expectedly
# not used).
dummy-variables-rgx=_$|dummy
# List of additional names supposed to be defined in builtins. Remember that
# you should avoid to define new builtins when possible.
additional-builtins=
[TYPECHECK]
# Tells whether missing members accessed in mixin class should be ignored. A
# mixin class is detected if its name ends with "mixin" (case insensitive).
ignore-mixin-members=yes
# List of module names for which member attributes should not be checked
# (useful for modules/projects where namespaces are manipulated during runtime
# and thus existing member attributes cannot be deduced by static analysis
ignored-modules=
# List of classes names for which member attributes should not be checked
# (useful for classes with attributes dynamically set).
ignored-classes=SQLObject
# When zope mode is activated, add a predefined set of Zope acquired attributes
# to generated-members.
zope=no
# List of members which are set dynamically and missed by pylint inference
# system, and so shouldn't trigger E0201 when accessed. Python regular
# expressions are accepted.
generated-members=REQUEST,acl_users,aq_parent
[FORMAT]
# Maximum number of characters on a single line.
max-line-length=80
# Regexp for a line that is allowed to be longer than the limit.
ignore-long-lines=^\s*(# )?<?https?://\S+>?$
# Allow the body of an if to be on the same line as the test if there is no
# else.
single-line-if-stmt=no
# List of optional constructs for which whitespace checking is disabled
no-space-check=trailing-comma,dict-separator
# Maximum number of lines in a module
max-module-lines=10000
# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
# tab).
indent-string=' '
# Number of spaces of indent required inside a hanging or continued line.
indent-after-paren=4
[LOGGING]
# Logging modules to check that the string format arguments are in logging
# function parameter format
logging-modules=logging
[BASIC]
# Required attributes for module, separated by a comma
#required-attributes=
# List of builtins function names that should not be used, separated by a comma
bad-functions=map,filter,apply,input,file
# Good variable names which should always be accepted, separated by a comma
good-names=i,j,k,ex,Run,_
# Bad variable names which should always be refused, separated by a comma
bad-names=foo,bar,baz,toto,tutu,tata
# Colon-delimited sets of names that determine each other's naming style when
# the name regexes allow several styles.
name-group=
# Include a hint for the correct naming format with invalid-name
include-naming-hint=no
# Regular expression matching correct function names
function-rgx=[a-z_][a-z0-9_]{2,30}$
# Naming hint for function names
function-name-hint=[a-z_][a-z0-9_]{2,30}$
# Regular expression matching correct variable names
variable-rgx=[a-z_][a-z0-9_]{2,30}$
# Naming hint for variable names
variable-name-hint=[a-z_][a-z0-9_]{2,30}$
# Regular expression matching correct constant names
const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$
# Naming hint for constant names
const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$
# Regular expression matching correct attribute names
attr-rgx=[a-z_][a-z0-9_]{2,30}$
# Naming hint for attribute names
attr-name-hint=[a-z_][a-z0-9_]{2,30}$
# Regular expression matching correct argument names
argument-rgx=[a-z_][a-z0-9_]{2,30}$
# Naming hint for argument names
argument-name-hint=[a-z_][a-z0-9_]{2,30}$
# Regular expression matching correct class attribute names
class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
# Naming hint for class attribute names
class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
# Regular expression matching correct inline iteration names
inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
# Naming hint for inline iteration names
inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$
# Regular expression matching correct class names
class-rgx=[A-Z_][a-zA-Z0-9]+$
# Naming hint for class names
class-name-hint=[A-Z_][a-zA-Z0-9]+$
# Regular expression matching correct module names
module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
# Naming hint for module names
module-name-hint=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
# Regular expression matching correct method names
method-rgx=[a-z_][a-z0-9_]{2,30}$
# Naming hint for method names
method-name-hint=[a-z_][a-z0-9_]{2,30}$
# Regular expression which should only match function or class names that do
# not require a docstring.
no-docstring-rgx=__.*__
# Minimum line length for functions/classes that require docstrings, shorter
# ones are exempt.
docstring-min-length=-1
[IMPORTS]
# Deprecated modules which should not be used, separated by a comma
deprecated-modules=regsub,TERMIOS,Bastion,rexec
# Create a graph of every (i.e. internal and external) dependencies in the
# given file (report RP0402 must not be disabled)
import-graph=
# Create a graph of external dependencies in the given file (report RP0402 must
# not be disabled)
ext-import-graph=
# Create a graph of internal dependencies in the given file (report RP0402 must
# not be disabled)
int-import-graph=
[CLASSES]
# List of interface methods to ignore, separated by a comma. This is used for
# instance to not check methods defines in Zope's Interface base class.
#ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by
# List of method names used to declare (i.e. assign) instance attributes.
defining-attr-methods=__init__,__new__,setUp
# List of valid names for the first argument in a class method.
valid-classmethod-first-arg=cls
# List of valid names for the first argument in a metaclass class method.
valid-metaclass-classmethod-first-arg=mcs
[DESIGN]
# Maximum number of arguments for function / method
max-args=5
# Argument names that match this expression will be ignored. Default to name
# with leading underscore
ignored-argument-names=_.*
# Maximum number of locals for function / method body
max-locals=15
# Maximum number of return / yield for function / method body
max-returns=6
# Maximum number of branch for function / method body
max-branches=12
# Maximum number of statements in function / method body
max-statements=50
# Maximum number of parents for a class (see R0901).
max-parents=7
# Maximum number of attributes for a class (see R0902).
max-attributes=7
# Minimum number of public methods for a class (see R0903).
min-public-methods=2
# Maximum number of public methods for a class (see R0904).
max-public-methods=20
[EXCEPTIONS]
# Exceptions that will emit a warning when being caught. Defaults to
# "Exception"
overgeneral-exceptions=Exception

111
vendor/riscv-tests/debug/rbb_daisychain.py vendored Executable file
View file

@ -0,0 +1,111 @@
#!/usr/bin/python3
import argparse
import sys
import socket
# https://github.com/ntfreak/openocd/blob/master/doc/manual/jtag/drivers/remote_bitbang.txt
class Tap:
def __init__(self, port):
self.port = port
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.connect(("localhost", port))
def execute(self, commands):
sent = self.socket.send(commands)
assert len(commands) == sent
read_count = 0
for command in commands:
if command == ord('R'):
read_count += 1
result = b""
while len(result) < read_count:
result += self.socket.recv(read_count - len(result))
assert len(result) == read_count
return result
class Chain:
def __init__(self, debug=False):
self.debug = debug
self.taps = []
def append(self, tap):
self.taps.append(tap)
def execute(self, commands):
values = []
for i, tap in enumerate(self.taps):
tmp_commands = []
for command in commands:
if i > 0 and ord('0') <= command <= ord('7'):
# Replace TDI with the value from the previous TAP.
v = values.pop(0)
command &= 0xfe
if v == ord('1'):
command |= 1
if i < len(self.taps) - 1:
if command != ord('R'):
tmp_commands.append(command)
if ord('0') <= command <= ord('7'):
# Read TDO before every scan.
tmp_commands.append(ord('R'))
else:
tmp_commands.append(command)
assert len(values) == 0
values = list(tap.execute(bytes(tmp_commands)))
if self.debug:
sys.stdout.write(f" {i} {bytes(tmp_commands)!r} -> "
f"{bytes(values)!r}\n")
return bytes(values)
def main():
parser = argparse.ArgumentParser(
description='Combine multiple remote_bitbang processes into a '
'single scan-chain.')
parser.add_argument("listen_port", type=int,
help="port to listen on")
parser.add_argument("tap_port", nargs="+", type=int,
help="port of a remote_bitbang TAP to connect to")
parser.add_argument("--debug", action='store_true',
help="Print out debug messages.")
args = parser.parse_args()
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(("localhost", args.listen_port))
server.listen(1)
chain = Chain(args.debug)
for port in args.tap_port:
chain.append(Tap(port))
sys.stdout.write(f"Listening on port {server.getsockname()[1]}.\n")
sys.stdout.flush()
while True:
(client, _) = server.accept()
while True:
try:
commands = client.recv(4096)
except (ConnectionResetError, OSError):
sys.stdout.write("Client disconnected due to exception.\n")
break
if len(commands) == 0:
sys.stdout.write("Client disconnected.\n")
break
if args.debug:
sys.stdout.write(f"{commands!r}\n")
result = chain.execute(commands)
if args.debug:
sys.stdout.write(f" -> {result!r}\n")
client.send(result)
client.close()
sys.stdout.flush()
if __name__ == '__main__':
sys.exit(main())

View file

@ -0,0 +1 @@
pexpect>=4.0.0

285
vendor/riscv-tests/debug/targets.py vendored Normal file
View file

@ -0,0 +1,285 @@
import importlib
import os.path
import re
import sys
import tempfile
import testlib
class Hart:
# XLEN of the hart. May be overridden with --32 or --64 command line
# options.
xlen = 0
# Will be autodetected (by running ExamineTarget) if left unset. Set to
# save a little time.
misa = None
# Path to linker script relative to the .py file where the target is
# defined. Defaults to <name>.lds.
link_script_path = None
# Implements dmode in tdata1 as described in the spec. Harts that need
# this value set to False are not compliant with the spec (but still usable
# as long as running code doesn't try to mess with triggers set by an
# external debugger).
honors_tdata1_hmode = True
# Address where a r/w/x block of RAM starts, together with its size.
ram = None
ram_size = None
# Address where we expect memory accesses to fail, usually because there is
# no device mapped to that location.
bad_address = None
# Number of instruction triggers the hart supports.
instruction_hardware_breakpoint_count = 0
# Defaults to target-<index>
name = None
# When reset, the PC must be at one of the values listed here.
# This is a list because on some boards the reset vector depends on
# jumpers.
reset_vectors = []
# system is set to an identifier of the system this hart belongs to. Harts
# within the same system are assumed to share memory, and to have unique
# hartids within that system. So for most cases the default value of None
# is fine.
system = None
# Supports the cease instruction, which causes a hart to become unavailable.
support_cease = False
def __init__(self, misa=None, system=None, link_script_path=None):
if misa:
self.misa = misa
if system:
self.system = system
if link_script_path:
self.link_script_path = link_script_path
def extensionSupported(self, letter):
# target.misa is set by testlib.ExamineTarget
if self.misa:
return self.misa & (1 << (ord(letter.upper()) - ord('A')))
return False
class Target:
# pylint: disable=too-many-instance-attributes
# List of Hart object instances, one for each hart in the target.
harts = []
# Name of the target. Defaults to the name of the class.
name = None
# GDB remotetimeout setting.
timeout_sec = 2
# Timeout waiting for the server to start up. This is different than the
# GDB timeout, which is how long GDB waits for commands to execute.
# The server_timeout is how long this script waits for the server to be
# ready for GDB connections.
server_timeout_sec = 60
# Path to OpenOCD configuration file relative to the .py file where the
# target is defined. Defaults to <name>.cfg.
openocd_config_path = None
# List of commands that should be executed in gdb after connecting but
# before starting the test.
gdb_setup = []
# Supports mtime at 0x2004000
supports_clint_mtime = True
# Implements custom debug registers like spike does. It seems unlikely any
# hardware will every do that.
implements_custom_test = False
# When true it indicates that reading invalid memory doesn't return an error
invalid_memory_returns_zero = False
# Supports simultaneous resume through hasel.
support_hasel = True
# Tests whose names are mentioned in this list will be skipped and marked
# as not applicable. This is a crude mechanism that can be handy, but in
# general it's better to define some property like those above that
# describe behavior of this target, and tests can use that to decide
# whether they are applicable or not.
skip_tests = []
# Set False if semihosting should not be tested in this configuration,
# because it doesn't work and isn't expected to work.
test_semihosting = True
# Set False if manual hwbps (breakpoints set by directly writing tdata*)
# isn't supposed to work.
support_manual_hwbp = True
# Set False if memory sampling is not supported due to OpenOCD
# limitation/hardware support.
support_memory_sampling = True
# Relative path to a FreeRTOS binary compiled from the spike demo project
# in https://github.com/FreeRTOS/FreeRTOS.
freertos_binary = None
# Internal variables:
directory = None
temporary_files = []
def __init__(self, path, parsed):
# Path to module.
self.path = path
self.directory = os.path.dirname(path)
self.server_cmd = parsed.server_cmd
self.sim_cmd = parsed.sim_cmd
self.debug_server = parsed.debug_server
self.temporary_binary = None
self.compiler_supports_v = True
Target.isolate = parsed.isolate
if not self.name:
self.name = type(self).__name__
# Default OpenOCD config file to <name>.cfg
if not self.openocd_config_path:
self.openocd_config_path = f"{self.name}.cfg"
self.openocd_config_path = os.path.join(self.directory,
self.openocd_config_path)
for i, hart in enumerate(self.harts):
hart.index = i
if not hasattr(hart, 'id'):
hart.id = i
if not hart.name:
hart.name = f"{self.name}-{i}"
# Default link script to <name>.lds
if not hart.link_script_path:
hart.link_script_path = f"{self.name}.lds"
hart.link_script_path = os.path.join(self.directory,
hart.link_script_path)
def create(self):
"""Create the target out of thin air, eg. start a simulator."""
def server(self, test):
"""Start the debug server that gdb connects to, eg. OpenOCD."""
return testlib.Openocd(server_cmd=self.server_cmd,
config=self.openocd_config_path,
timeout=self.server_timeout_sec,
freertos=test.freertos(),
debug_openocd=self.debug_server)
def do_compile(self, hart, *sources):
binary_name = (
self.name + "_" +
os.path.basename(os.path.splitext(sources[0])[0]) + "-" +
f"{hart.misa:x}")
if Target.isolate:
# pylint: disable-next=consider-using-with
self.temporary_binary = tempfile.NamedTemporaryFile(
prefix=binary_name + "_")
binary_name = self.temporary_binary.name
Target.temporary_files.append(self.temporary_binary)
args = list(sources) + [
"programs/entry.S", "programs/init.c",
f"-DNHARTS={len(self.harts)}",
"-I", "../env",
"-T", hart.link_script_path,
"-nostartfiles",
"-mcmodel=medany",
f"-DXLEN={hart.xlen}",
"-o", binary_name]
if hart.extensionSupported('e'):
args.append("-march=rv32e")
args.append("-mabi=ilp32e")
args.append("-DRV32E")
else:
march = f"rv{hart.xlen}ima"
for letter in "fdc":
if hart.extensionSupported(letter):
march += letter
if hart.extensionSupported("v") and self.compiler_supports_v:
march += "v"
args.append(f"-march={march}")
if hart.xlen == 32:
args.append("-mabi=ilp32")
else:
args.append(f"-mabi=lp{hart.xlen}")
testlib.compile(args)
return binary_name
def compile(self, hart, *sources):
for _ in range(2):
try:
return self.do_compile(hart, *sources)
except testlib.CompileError as e:
# If the compiler doesn't support V, disable it from the
# current configuration. Eventually all gcc branches will
# support V, but we're not there yet.
m = re.search(r"Error: cannot find default versions of the "
r"ISA extension `(\w)'", e.stderr.decode())
if m and m.group(1) in "v":
extension = m.group(1)
print(f"Disabling extension {extension!r} because the "
"compiler doesn't support it.")
self.compiler_supports_v = False
else:
raise
return None
def add_target_options(parser):
parser.add_argument("target", help=".py file that contains definition for "
"the target to test with.")
parser.add_argument("--sim_cmd",
help="The command to use to start the actual target (e.g. "
"simulation)", default="spike")
parser.add_argument("--server_cmd",
help="The command to use to start the debug server (e.g. OpenOCD)")
parser.add_argument("--debug_server", action="store_true",
help="Open gdb in a separate terminal on the debug server")
xlen_group = parser.add_mutually_exclusive_group()
xlen_group.add_argument("--32", action="store_const", const=32,
dest="xlen", default=0, help="Force the target to be 32-bit.")
xlen_group.add_argument("--64", action="store_const", const=64,
dest="xlen", default=0, help="Force the target to be 64-bit.")
parser.add_argument("--isolate", action="store_true",
help="Try to run in such a way that multiple instances can run at "
"the same time. This may make it harder to debug a failure if it "
"does occur.")
def target(parsed):
directory = os.path.dirname(parsed.target)
filename = os.path.basename(parsed.target)
module_name = os.path.splitext(filename)[0]
sys.path.append(directory)
module = importlib.import_module(module_name)
found = []
for name in dir(module):
definition = getattr(module, name)
if isinstance(definition, type) and issubclass(definition, Target):
found.append(definition)
assert len(found) == 1, (f"{parsed.target} does not define exactly one "
"subclass of targets.Target")
t = found[0](parsed.target, parsed)
assert t.harts, f"{t.name} doesn't have any harts defined!"
if parsed.xlen > 0:
for h in t.harts:
if h.xlen == 0:
h.xlen = parsed.xlen
elif h.xlen != parsed.xlen:
raise Exception("The target hart specified an XLEN of "
f"{h.xlen}, but the command line specified an XLEN of "
f"{parsed.xlen}. They must match.")
return t

View file

@ -0,0 +1,33 @@
adapter_khz 10000
interface remote_bitbang
remote_bitbang_host $::env(REMOTE_BITBANG_HOST)
remote_bitbang_port $::env(REMOTE_BITBANG_PORT)
set _CHIPNAME riscv
jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x10e31913
set _TARGETNAME $_CHIPNAME.cpu
if {$::env(USE_FREERTOS)} {
target create $_TARGETNAME riscv -chain-position $_TARGETNAME -rtos FreeRTOS
} else {
target create $_TARGETNAME riscv -chain-position $_TARGETNAME
}
$_TARGETNAME configure -work-area-phys $::env(WORK_AREA) -work-area-size 8096 -work-area-backup 1
gdb_report_data_abort enable
gdb_report_register_access_error enable
# Expose an unimplemented CSR so we can test non-existent register access
# behavior.
riscv expose_csrs 2288
riscv expose_custom 1,12345-12348
init
set challenge [riscv authdata_read]
riscv authdata_write [expr $challenge + 1]
halt
arm semihosting enable

View file

@ -0,0 +1,40 @@
# Connect to a mult-icore RISC-V target, exposing each hart as a thread.
adapter_khz 10000
interface remote_bitbang
remote_bitbang_host $::env(REMOTE_BITBANG_HOST)
remote_bitbang_port $::env(REMOTE_BITBANG_PORT)
set _CHIPNAME riscv
jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x10e31913
set _TARGETNAME_0 $_CHIPNAME.cpu0
set _TARGETNAME_1 $_CHIPNAME.cpu1
target create $_TARGETNAME_0 riscv -chain-position $_CHIPNAME.cpu -rtos hwthread
target create $_TARGETNAME_1 riscv -chain-position $_CHIPNAME.cpu -coreid 1
target smp $_TARGETNAME_0 $_TARGETNAME_1
gdb_report_data_abort enable
gdb_report_register_access_error enable
# Expose an unimplemented CSR so we can test non-existent register access
# behavior.
foreach t [target names] {
targets $t
riscv expose_csrs 2288
riscv expose_custom 1,12345-12348
}
riscv resume_order reversed
init
set challenge [riscv authdata_read]
riscv authdata_write [expr $challenge + 1]
halt
foreach t [target names] {
targets $t
arm semihosting enable
}

View file

@ -0,0 +1,36 @@
# Connect to a mult-icore RISC-V target, exposing each hart as a thread.
adapter_khz 10000
interface remote_bitbang
remote_bitbang_host $::env(REMOTE_BITBANG_HOST)
remote_bitbang_port $::env(REMOTE_BITBANG_PORT)
set _CHIPNAME riscv
jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x10e31913
set _TARGETNAME_0 $_CHIPNAME.cpu0
set _TARGETNAME_1 $_CHIPNAME.cpu1
target create $_TARGETNAME_0 riscv -chain-position $_CHIPNAME.cpu -coreid 0
target create $_TARGETNAME_1 riscv -chain-position $_CHIPNAME.cpu -coreid 1
gdb_report_data_abort enable
gdb_report_register_access_error enable
# Expose an unimplemented CSR so we can test non-existent register access
# behavior.
foreach t [target names] {
targets $t
riscv expose_csrs 2288
riscv expose_custom 1,12345-12348
}
init
set challenge [riscv authdata_read]
riscv authdata_write [expr $challenge + 1]
foreach t [target names] {
targets $t
halt
arm semihosting enable
}

View file

@ -0,0 +1,46 @@
# Connect to a mult-icore RISC-V target, exposing each hart as a thread.
adapter_khz 10000
interface remote_bitbang
remote_bitbang_host $::env(REMOTE_BITBANG_HOST)
remote_bitbang_port $::env(REMOTE_BITBANG_PORT)
jtag newtap riscv.0 cpu -irlen 5 -expected-id 0x10e31913
jtag newtap riscv.1 cpu -irlen 5 -expected-id 0x10e31913
target create riscv.0.cpu0 riscv -chain-position riscv.0.cpu -coreid 0
target create riscv.0.cpu1 riscv -chain-position riscv.0.cpu -coreid 1
target create riscv.1.cpu0 riscv -chain-position riscv.1.cpu -coreid 0
target create riscv.1.cpu1 riscv -chain-position riscv.1.cpu -coreid 1
riscv.0.cpu0 configure -work-area-phys $::env(WORK_AREA) -work-area-size 8096 -work-area-backup 1
riscv.0.cpu1 configure -work-area-phys $::env(WORK_AREA) -work-area-size 8096 -work-area-backup 1
riscv.1.cpu0 configure -work-area-phys $::env(WORK_AREA) -work-area-size 8096 -work-area-backup 1
riscv.1.cpu1 configure -work-area-phys $::env(WORK_AREA) -work-area-size 8096 -work-area-backup 1
gdb_report_data_abort enable
gdb_report_register_access_error enable
# Expose an unimplemented CSR so we can test non-existent register access
# behavior.
foreach t [target names] {
targets $t
riscv expose_csrs 2288
riscv expose_custom 1,12345-12348
}
init
targets riscv.0.cpu0
set challenge [riscv authdata_read]
riscv authdata_write [expr $challenge + 1]
targets riscv.1.cpu0
set challenge [riscv authdata_read]
riscv authdata_write [expr $challenge + 1]
foreach t [target names] {
targets $t
halt
arm semihosting enable
}

View file

@ -0,0 +1,30 @@
import spike32 # pylint: disable=import-error
import spike64 # pylint: disable=import-error
import targets
import testlib
class multispike(targets.Target):
harts = [
spike32.spike32_hart(misa=0x4034112d, system=0),
spike32.spike32_hart(misa=0x4034112d, system=0),
spike64.spike64_hart(misa=0x8000000000341129, system=1),
spike64.spike64_hart(misa=0x8000000000341129, system=1)]
openocd_config_path = "spike-multi.cfg"
timeout_sec = 30
server_timeout_sec = 120
implements_custom_test = True
support_hasel = False
support_memory_sampling = False # Needs SBA
def create(self):
return testlib.MultiSpike(
[
testlib.Spike(self, isa="RV64IMAFDV",
support_hasel=False, support_abstract_csr=False,
vlen=512, elen=64, harts=self.harts[2:]),
testlib.Spike(self, isa="RV32IMAFDCV",
support_abstract_csr=True, support_haltgroups=False,
# elen must be at least 64 because D is supported.
elen=64, harts=self.harts[:2]),
])

View file

@ -0,0 +1,16 @@
import spike32 # pylint: disable=import-error
import targets
import testlib
class spike32_2(targets.Target):
harts = [spike32.spike32_hart(misa=0x40341129),
spike32.spike32_hart(misa=0x40341129)]
openocd_config_path = "spike-2-hwthread.cfg"
timeout_sec = 5
implements_custom_test = True
support_memory_sampling = False # not supported without sba
def create(self):
return testlib.Spike(self, isa="RV32IMAFDV", support_hasel=True,
support_haltgroups=False)

View file

@ -0,0 +1,16 @@
import spike32 # pylint: disable=import-error
import targets
import testlib
class spike32_2(targets.Target):
harts = [spike32.spike32_hart(misa=0x40141125),
spike32.spike32_hart(misa=0x40141125)]
openocd_config_path = "spike-2.cfg"
timeout_sec = 30
implements_custom_test = True
def create(self):
return testlib.Spike(self, isa="RV32IMAFC", progbufsize=0, dmi_rti=4,
support_abstract_csr=True, support_abstract_fpr=True,
support_haltgroups=False)

View file

@ -0,0 +1,38 @@
OUTPUT_ARCH( "riscv" )
SECTIONS
{
/* Leave some space for pk's data structures, which includes tohost/fromhost
* which are special addresses we ought to leave alone. */
. = 0x10110000;
.text :
{
*(.text.entry)
*(.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 */
__bss_start = .;
.sbss : {
*(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.scommon)
}
.bss : { *(.bss) }
__bss_end = .;
__malloc_start = .;
. = . + 512;
/* End of uninitalized data segement */
_end = .;
}

View file

@ -0,0 +1,26 @@
import targets
import testlib
class spike32_hart(targets.Hart):
xlen = 32
ram = 0x10100000
ram_size = 0x10000000
bad_address = ram - 8
instruction_hardware_breakpoint_count = 4
reset_vectors = [0x1000]
link_script_path = "spike32.lds"
class spike32(targets.Target):
harts = [spike32_hart(misa=0x4034112d)]
openocd_config_path = "spike-1.cfg"
timeout_sec = 30
implements_custom_test = True
support_memory_sampling = False # Needs SBA
freertos_binary = "bin/RTOSDemo32.axf"
def create(self):
# 64-bit FPRs on 32-bit target
return testlib.Spike(self, isa="RV32IMAFDCV", dmi_rti=4,
support_abstract_csr=True, support_haltgroups=False,
# elen must be at least 64 because D is supported.
elen=64)

View file

@ -0,0 +1,20 @@
import spike64 # pylint: disable=import-error
import targets
import testlib
class spike64_2(targets.Target):
harts = [spike64.spike64_hart(misa=0x8000000000341129),
spike64.spike64_hart(misa=0x8000000000341129)]
openocd_config_path = "spike-2-hwthread.cfg"
# Increased timeout because we use abstract_rti to artificially slow things
# down.
timeout_sec = 20
implements_custom_test = True
support_hasel = False
support_memory_sampling = False # Needs SBA
def create(self):
return testlib.Spike(self, isa="RV64IMAFDV", abstract_rti=30,
support_hasel=False, support_abstract_csr=False,
vlen=512, elen=64)

View file

@ -0,0 +1,19 @@
import spike64 # pylint: disable=import-error
import targets
import testlib
class spike64_2_rtos(targets.Target):
harts = [spike64.spike64_hart(misa=0x8000000000141129),
spike64.spike64_hart(misa=0x8000000000141129)]
openocd_config_path = "spike-rtos.cfg"
timeout_sec = 60
implements_custom_test = True
support_hasel = False
test_semihosting = False
support_manual_hwbp = False # not supported with `-rtos riscv`
support_memory_sampling = False # not supported with `-rtos riscv`
def create(self):
return testlib.Spike(self, abstract_rti=30, support_hasel=False,
support_abstract_csr=False)

View file

@ -0,0 +1,15 @@
import spike64 # pylint: disable=import-error
import targets
import testlib
class spike64_2(targets.Target):
harts = [spike64.spike64_hart(misa=0x8000000000141129),
spike64.spike64_hart(misa=0x8000000000141129)]
openocd_config_path = "spike-2.cfg"
timeout_sec = 5
implements_custom_test = True
support_memory_sampling = False # Needs SBA
def create(self):
return testlib.Spike(self)

View file

@ -0,0 +1,36 @@
OUTPUT_ARCH( "riscv" )
SECTIONS
{
. = 0x1212340000;
.text :
{
*(.text.entry)
*(.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 */
__bss_start = .;
.sbss : {
*(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.scommon)
}
.bss : { *(.bss) }
__bss_end = .;
__malloc_start = .;
. = . + 512;
/* End of uninitalized data segement */
_end = .;
}

View file

@ -0,0 +1,25 @@
import targets
import testlib
class spike64_hart(targets.Hart):
xlen = 64
ram = 0x1212340000
ram_size = 0x10000000
bad_address = ram - 8
instruction_hardware_breakpoint_count = 4
reset_vectors = [0x1000]
link_script_path = "spike64.lds"
misa = 0x8000000000141125
class spike64(targets.Target):
harts = [spike64_hart()]
openocd_config_path = "spike-1.cfg"
timeout_sec = 30
implements_custom_test = True
freertos_binary = "bin/RTOSDemo64.axf"
def create(self):
# 32-bit FPRs only
return testlib.Spike(self, isa="RV64IMAFC", progbufsize=0,
abstract_rti=30, support_abstract_csr=True,
support_abstract_fpr=True)

View file

@ -0,0 +1,13 @@
import targets
class E300Hart(targets.Hart):
xlen = 32
ram = 0x80000000
ram_size = 64 * 1024
instruction_hardware_breakpoint_count = 2
link_script_path = "Freedom.lds"
class E300(targets.Target):
openocd_config_path = "Freedom.cfg"
harts = [E300Hart()]
invalid_memory_returns_zero = True

Some files were not shown because too many files have changed in this diff Show more