提交 09968539 编写于 作者: W William Wang

Merge remote-tracking branch 'origin/master' into rebase-xs-to-master

......@@ -47,6 +47,10 @@ LDFLAGS += $(CFLAGS_BUILD)
NAME = nemu-$(ENGINE)
ifdef CONFIG_MEM_COMPRESS
LDFLAGS += -lz
endif
ifndef CONFIG_SHARE
LDFLAGS += -lreadline -ldl -pie
else
......
#
# Automatically generated file; DO NOT EDIT.
# NEMU Configuration Menu
#
# CONFIG_ISA_x86 is not set
# CONFIG_ISA_mips32 is not set
# CONFIG_ISA_riscv32 is not set
CONFIG_ISA_riscv64=y
CONFIG_ISA="riscv64"
CONFIG_ILEN_MIN=2
CONFIG_ISA64=y
#
# ISA-dependent Options for riscv64
#
CONFIG_CLINT_MMIO=0xa2000000
CONFIG_RVV_010=y
# end of ISA-dependent Options for riscv64
CONFIG_ENGINE_INTERPRETER=y
CONFIG_ENGINE="interpreter"
CONFIG_MODE_SYSTEM=y
# CONFIG_MODE_USER is not set
#
# Build Options
#
CONFIG_CC_GCC=y
# CONFIG_CC_GPP is not set
# CONFIG_CC_CLANG is not set
CONFIG_CC="gcc"
CONFIG_CC_O0=y
# CONFIG_CC_O1 is not set
# CONFIG_CC_O2 is not set
# CONFIG_CC_O3 is not set
CONFIG_CC_OPT="-O0"
CONFIG_CC_LTO=y
CONFIG_CC_DEBUG=y
# CONFIG_CC_ASAN is not set
# CONFIG_SHARE is not set
# end of Build Options
#
# Testing and Debugging
#
# CONFIG_DEBUG is not set
# CONFIG_DIFFTEST is not set
CONFIG_DIFFTEST_REF_PATH="none"
CONFIG_DIFFTEST_REF_NAME="none"
CONFIG_DETERMINISTIC=y
# CONFIG_IQUEUE is not set
# end of Testing and Debugging
#
# Memory Configuration
#
CONFIG_MBASE=0x80000000
CONFIG_MSIZE=0x8000000
CONFIG_PC_RESET_OFFSET=0x0
CONFIG_USE_MMAP=y
CONFIG_MEM_RANDOM=y
# end of Memory Configuration
CONFIG_DEVICE=y
CONFIG_HAS_PORT_IO=y
CONFIG_HAS_SERIAL=y
CONFIG_SERIAL_PORT=0x3f8
CONFIG_SERIAL_MMIO=0xa10003f8
# CONFIG_SERIAL_INPUT_FIFO is not set
CONFIG_HAS_TIMER=y
CONFIG_RTC_PORT=0x48
CONFIG_RTC_MMIO=0xa1000048
# CONFIG_HAS_KEYBOARD is not set
# CONFIG_HAS_VGA is not set
# CONFIG_HAS_AUDIO is not set
# CONFIG_HAS_DISK is not set
CONFIG_HAS_SDCARD=y
CONFIG_SDCARD_CTL_MMIO=0xa3000000
CONFIG_SDCARD_IMG_PATH=""
CONFIG_FPU_HOST=y
# CONFIG_FPU_SOFT is not set
# CONFIG_FPU_NONE is not set
# CONFIG_AC_HOST is not set
# CONFIG_AC_SOFT is not set
CONFIG_AC_NONE=y
#
# Miscellaneous
#
CONFIG_TIMER_GETTIMEOFDAY=y
# CONFIG_TIMER_CLOCK_GETTIME is not set
CONFIG_RT_CHECK=y
CONFIG_PERF_OPT=y
CONFIG_TCACHE_SIZE=8192
CONFIG_BB_LIST_SIZE=1024
CONFIG_BB_POOL_SIZE=1024
# CONFIG_DISABLE_INSTR_CNT is not set
CONFIG_ENABLE_INSTR_CNT=y
# end of Miscellaneous
......@@ -14,6 +14,7 @@ CONFIG_ISA64=y
# ISA-dependent Options for riscv64
#
CONFIG_CLINT_MMIO=0x38000000
# CONFIG_RVV_010 is not set
# end of ISA-dependent Options for riscv64
CONFIG_ENGINE_INTERPRETER=y
......@@ -34,7 +35,7 @@ CONFIG_CC_O2=y
# CONFIG_CC_O3 is not set
CONFIG_CC_OPT="-O2"
CONFIG_CC_LTO=y
# CONFIG_CC_DEBUG is not set
CONFIG_CC_DEBUG=y
# CONFIG_CC_ASAN is not set
# end of Build Options
......@@ -55,6 +56,7 @@ CONFIG_MSIZE=0x200000000
CONFIG_PC_RESET_OFFSET=0x0
CONFIG_USE_MMAP=y
# CONFIG_MEM_RANDOM is not set
# CONFIG_MEM_COMPRESS is not set
# end of Memory Configuration
CONFIG_FPU_HOST=y
......
......@@ -14,6 +14,7 @@ CONFIG_ISA64=y
# ISA-dependent Options for riscv64
#
CONFIG_CLINT_MMIO=0x38000000
# CONFIG_RVV_010 is not set
# end of ISA-dependent Options for riscv64
CONFIG_ENGINE_INTERPRETER=y
......@@ -36,7 +37,6 @@ CONFIG_CC_OPT="-O2"
CONFIG_CC_LTO=y
# CONFIG_CC_DEBUG is not set
# CONFIG_CC_ASAN is not set
# CONFIG_SHARE is not set
# end of Build Options
#
......@@ -58,6 +58,7 @@ CONFIG_MSIZE=0x200000000
CONFIG_PC_RESET_OFFSET=0x0
CONFIG_USE_MMAP=y
# CONFIG_MEM_RANDOM is not set
# CONFIG_MEM_COMPRESS is not set
# end of Memory Configuration
CONFIG_DEVICE=y
......@@ -92,13 +93,18 @@ CONFIG_AC_HOST=y
# CONFIG_AC_SOFT is not set
# CONFIG_AC_NONE is not set
#
# Processor difftest reference config
#
# CONFIG_SHARE is not set
# end of Processor difftest reference config
#
# Miscellaneous
#
CONFIG_TIMER_GETTIMEOFDAY=y
# CONFIG_TIMER_CLOCK_GETTIME is not set
CONFIG_RT_CHECK=y
CONFIG_LARGE_COPY=y
CONFIG_PERF_OPT=y
CONFIG_TCACHE_SIZE=8192
CONFIG_BB_LIST_SIZE=1024
......
......@@ -16,6 +16,8 @@ typedef struct {
IFDEF(CONFIG_ISA_x86, rtlreg_t val);
IFDEF(CONFIG_ISA_x86, uint8_t type);
IFDEF(CONFIG_ISA_x86, uint8_t reg);
IFDEF(CONFIG_RVV_010, rtlreg_t val);
IFDEF(CONFIG_RVV_010, uint8_t reg);
IFDEF(CONFIG_DEBUG, char str[OP_STR_SIZE]);
} Operand;
......@@ -47,8 +49,17 @@ typedef struct Decode {
uint8_t type;
ISADecodeInfo isa;
IFDEF(CONFIG_DEBUG, char logbuf[80]);
#ifdef CONFIG_RVV_010
// for vector
int v_width;
uint32_t vm;
uint32_t src_vmode;
rtlreg_t tmp_reg[4];
#endif // CONFIG_RVV_010
} Decode;
#define id_src1 (&s->src1)
#define id_src2 (&s->src2)
#define id_dest (&s->dest)
......
......@@ -86,5 +86,16 @@ static inline def_rtl(trap, vaddr_t ret_pc, word_t NO) {
rtl_hostcall(s, HOSTCALL_TRAP, t0, t0, NULL, NO);
rtl_jr(s, t0);
}
static inline def_rtl(mux, rtlreg_t* dest, const rtlreg_t* cond, const rtlreg_t* src1, const rtlreg_t* src2) {
// dest <- (cond ? src1 : src2)
// TODO();
rtl_setrelopi(s, RELOP_EQ, t0, cond, 0);
rtl_subi(s, t0, t0, 1);
// t0 = mask
rtl_and(s, s2, src1, t0);
rtl_not(s, t0, t0);
rtl_and(s, t0, src2, t0);
rtl_or(s, dest, t0, s2);
}
#endif
......@@ -49,7 +49,7 @@ static void update_instr_cnt() {
#if defined(CONFIG_ENABLE_INSTR_CNT)
int n_batch = n_remain_total >= BATCH_SIZE ? BATCH_SIZE : n_remain_total;
uint32_t n_executed = n_batch - n_remain;
n_remain_total -= n_executed;
n_remain_total -= (n_remain_total > n_executed) ? n_executed : n_remain_total;
IFNDEF(CONFIG_DEBUG, g_nr_guest_instr += n_executed);
n_remain = n_batch; // clean n_remain
#endif
......
......@@ -32,6 +32,10 @@ config SERIAL_MMIO
config SERIAL_INPUT_FIFO
bool "Enable input FIFO with /tmp/nemu.serial"
default n
config SERIAL_UARTLITE
bool "Use uartlite as the serial (default: 16550)"
default n
endif # HAS_SERIAL
if HAS_UARTLITE
......
......@@ -114,6 +114,12 @@ static void serial_io_handler(uint32_t offset, int len, bool is_write) {
}
void init_serial() {
#ifdef CONFIG_SERIAL_UARTLITE
void init_uartlite();
init_uartlite();
// to avoid unused-function warning
(void)serial_io_handler;
#else
serial_base = new_space(8);
add_pio_map ("serial", CONFIG_SERIAL_PORT, serial_base, 8, serial_io_handler);
add_mmio_map("serial", CONFIG_SERIAL_MMIO, serial_base, 8, serial_io_handler);
......@@ -122,4 +128,5 @@ void init_serial() {
init_fifo();
preset_input();
#endif
#endif // CONFIG_SERIAL_UARTLITE
}
......@@ -114,14 +114,6 @@ static void serial_io_handler(uint32_t offset, int len, bool is_write) {
}
}
// static void preset_input() {
// char buf[] = debian_cmd;
// int i;
// for (i = 0; i < strlen(buf); i ++) {
// serial_enqueue(buf[i]);
// }
// }
void init_uartlite() {
serial_base = new_space(0xd);
add_pio_map("uartlite", CONFIG_UARTLITE_PORT, serial_base, 0xd, serial_io_handler);
......
......@@ -4,4 +4,6 @@ config CLINT_MMIO
hex "MMIO address of CLINT"
default 0xa2000000
config RVV_010
bool "Experimental RISC-V Vector Extension v0.10"
endmenu
......@@ -27,6 +27,13 @@ static void csr_prepare() {
cpu.stval = stval->val;
cpu.mtvec = mtvec->val;
cpu.stvec = stvec->val;
#ifdef CONFIG_RVV_010
cpu.vtype = vtype->val;
cpu.vstart = vstart->val;
cpu.vxsat = vxsat->val;
cpu.vxrm = vxrm->val;
cpu.vl = vl->val;
#endif // CONFIG_RVV_010
}
static void csr_writeback() {
......@@ -48,6 +55,13 @@ static void csr_writeback() {
stval->val = cpu.stval;
mtvec->val = cpu.mtvec;
stvec->val = cpu.stvec;
#ifdef CONFIG_RVV_010
vtype->val = cpu.vtype;
vstart->val = cpu.vstart;
vxsat->val = cpu.vxsat;
vxrm->val = cpu.vxrm;
vl->val = cpu.vl;
#endif //CONFIG_RVV_010
}
void isa_difftest_regcpy(void *dut, bool direction) {
......
#ifndef __RISCV64_ISA_ALL_INSTR_H__
#define __RISCV64_ISA_ALL_INSTR_H__
#include <cpu/decode.h>
#include "../local-include/rtl.h"
......@@ -21,6 +23,43 @@
#define SYS_INSTR_TERNARY(f) f(system)
#endif
#ifdef CONFIG_RVV_010
#define VECTOR_INSTR_TERNARY(f) \
f(vadd) f(vsub) f(vrsub) f(vminu) f(vmin) \
f(vmaxu) f(vmax) f(vand) f(vor) f(vxor) \
f(vrgather) \
f(vadc) f(vmadc) f(vsbc) f(vmsbc) \
f(vmerge) f(vmseq) f(vmsne) f(vmsltu) \
f(vmslt) f(vmsleu) f(vmsle) f(vmsgtu) \
f(vmsgt) f(vsaddu) f(vsadd) f(vssubu) \
f(vssub) f(vaadd) f(vsll) f(vasub) \
f(vsmul) f(vsrl) f(vsra) \
f(vssra) f(vnsrl) f(vnsra) f(vnclipu) \
f(vnclip) f(vssrl) f(vwredsumu) f(vwredsum) \
f(vdotu) f(vdot) f(vwsmaccu) f(vwsmacc) \
f(vwsmaccsu) f(vwsmaccus) f(vredsum) \
f(vredand) f(vredor) f(vredxor) f(vredminu) \
f(vredmin) f(vredmaxu) f(vredmax) f(vmpopc) \
f(vmfirst) f(vmunaryo) f(vcompress) f(vmandnot) \
f(vmand) f(vmor) f(vmxor) f(vmornot) f(vmnand) \
f(vmnor) f(vmxnor) f(vdivu) f(vdiv) f(vremu) \
f(vrem) f(vmulhu) f(vmul) f(vmulhsu) f(vmulh) \
f(vmadd) f(vnmsub) f(vmacc) f(vnmsac) f(vwaddu) \
f(vwadd) f(vwsub) f(vwsubu) f(vwaddu_w) f(vwadd_w) \
f(vwsubu_w) f(vwsub_w) f(vwmulu) f(vwmulsu) \
f(vwmul) f(vwmaccu) f(vwnmacc) f(vwmaccsu) \
f(vwmaccus) f(vlduu) f(vldsu) f(vldxu) \
f(vldus) f(vldss) f(vldxs) f(vstu) \
f(vsts) f(vstx) f(vstxu) f(vsetvl) \
f(vlduu_mmu) f(vldsu_mmu) f(vldxu_mmu) \
f(vldus_mmu) f(vldss_mmu) f(vldxs_mmu) f(vstu_mmu) \
f(vsts_mmu) f(vstx_mmu) f(vstxu_mmu) f(vslideup) f(vslidedown)
#else // CONFIG_RVV_010
#define VECTOR_INSTR_TERNARY(f)
#endif // CONFIG_RVV_010
//
#define FLOAT_INSTR_TERNARY(f) \
f(fadds) f(fsubs) f(fmuls) f(fdivs) f(fmins) f(fmaxs) \
f(faddd) f(fsubd) f(fmuld) f(fdivd) f(fmind) f(fmaxd) \
......@@ -71,6 +110,9 @@
f(p_inc) f(p_dec) \
AMO_INSTR_TERNARY(f) \
SYS_INSTR_TERNARY(f) \
FLOAT_INSTR_TERNARY(f)
FLOAT_INSTR_TERNARY(f) \
VECTOR_INSTR_TERNARY(f)
def_all_EXEC_ID();
#endif // __RISCV64_ISA_ALL_INSTR_H__
......@@ -2,6 +2,9 @@
#define __ISA_RISCV64_H__
#include <common.h>
#ifdef CONFIG_RVV_010
#include "../instr/rvv/vreg.h"
#endif // CONFIG_RVV_010
#define FORCE_RAISE_PF
......@@ -27,6 +30,18 @@ typedef struct {
uint64_t sstatus, scause, sepc;
uint64_t satp, mip, mie, mscratch, sscratch, mideleg, medeleg;
#ifdef CONFIG_RVV_010
//vector
union {
uint64_t _64[VENUM64];
uint32_t _32[VENUM32];
uint16_t _16[VENUM16];
uint8_t _8[VENUM8];
} vr[32];
uint64_t vstart;
uint64_t vxsat, vxrm, vl, vtype;
#endif // CONFIG_RVV_010
uint64_t mtval, stval, mtvec, stvec;
uint64_t mode;
......@@ -115,6 +130,52 @@ typedef struct {
uint32_t fmt : 2;
uint32_t funct5 : 5;
} fp;
#ifdef CONFIG_RVV_010
//vector-OP-V
struct {
uint32_t pad16 : 7;
uint32_t v_vd : 5;
uint32_t pad17 : 3;
uint32_t v_vs1 : 5;
uint32_t v_vs2 : 5;
uint32_t v_vm : 1;
uint32_t v_funct6 : 6;
} v_opv1;
struct {
uint32_t pad18 :15;
int32_t v_simm5 : 5;
uint32_t v_zimm :11;
uint32_t v_bigbit : 1;
} v_opv2;
struct {
uint32_t pad19 :15;
uint32_t v_imm5 : 5;
} v_opv3;
//vector-LOAD-FP
struct {
uint32_t pad20 :12;
uint32_t v_width : 3;
uint32_t pad21 : 5;
uint32_t v_lumop : 5;
uint32_t pad22 : 1;
uint32_t v_mop : 3;
uint32_t v_nf : 3;
} vldfp;
//vector-STORE-FP
struct {
uint32_t pad23 : 7;
uint32_t v_vs3 : 5;
uint32_t pad24 : 8;
uint32_t v_sumop : 5;
} vstfp;
//vector-AMO
struct {
uint32_t pad25 :26;
uint32_t v_wd : 1;
uint32_t v_amoop : 5;
} vamo;
#endif // CONFIG_RVV_010
uint32_t val;
} instr;
} riscv64_ISADecodeInfo;
......
......@@ -6,4 +6,7 @@
#include "../instr/rvd/exec.h"
#include "../instr/rva/exec.h"
#include "../instr/priv/exec.h"
#ifdef CONFIG_RVV_010
#include "../instr/rvv/exec.h"
#endif
#include "../instr/special.h"
......@@ -28,6 +28,12 @@ void init_isa() {
misa->extensions |= ext('d') | ext('f');
misa->mxl = 2; // XLEN = 64
#ifdef CONFIG_RVV_010
// vecotr
vl->val = 0;
vtype->val = 0; // actually should be 1 << 63 (set vill bit to forbidd)
#endif // CONFIG_RVV_010
memcpy(guest_to_host(RESET_VECTOR), img, sizeof(img));
IFNDEF(CONFIG_SHARE, init_clint());
......
......@@ -3,6 +3,7 @@
#include <cpu/decode.h>
#include <isa-all-instr.h>
def_all_THelper();
__attribute__((always_inline))
......@@ -21,6 +22,9 @@ static inline uint32_t get_instr(Decode *s) {
#include "rvc/decode.h"
#include "rvd/decode.h"
#include "priv/decode.h"
#ifdef CONFIG_RVV_010
#include "rvv/decode.h"
#endif // CONFIG_RVV_010
def_THelper(main) {
def_INSTR_IDTAB("??????? ????? ????? ??? ????? 00000 ??", I , load);
......@@ -42,6 +46,9 @@ def_THelper(main) {
def_INSTR_IDTAB("??????? ????? ????? ??? ????? 10010 ??", R4 , fmadd_dispatch);
def_INSTR_IDTAB("??????? ????? ????? ??? ????? 10011 ??", R4 , fmadd_dispatch);
def_INSTR_TAB ("??????? ????? ????? ??? ????? 10100 ??", op_fp);
#ifdef CONFIG_RVV_010
def_INSTR_IDTAB("??????? ????? ????? ??? ????? 10101 ??", OP_V , OP_V);
#endif // CONFIG_RVV_010
def_INSTR_IDTAB("??????? ????? ????? ??? ????? 11000 ??", B , branch);
def_INSTR_IDTAB("??????? ????? ????? ??? ????? 11001 ??", I , jalr_dispatch);
def_INSTR_TAB ("??????? ????? ????? ??? ????? 11010 ??", nemu_trap);
......
......@@ -5,6 +5,9 @@ static int table_fmadd_d_dispatch(Decode *s);
static inline def_DopHelper(fr){
op->preg = &fpreg_l(val);
print_Dop(op->str, OP_STR_SIZE, "%s", fpreg_name(val, 4));
#ifdef CONFIG_RVV_010
op->reg = val;
#endif // CONFIG_RVV_010
}
static inline def_DHelper(fr) {
......@@ -45,30 +48,122 @@ static inline def_DHelper(r2fr){
decode_op_fr(s, id_dest, s->isa.instr.fp.rd, false);
}
#ifdef CONFIG_RVV_010
bool vp_enable();
def_THelper(vload) {
def_INSTR_TAB("??? 000 ? ????? ????? ??? ????? ????? ??", vlduu);
def_INSTR_TAB("??? 010 ? ????? ????? ??? ????? ????? ??", vldsu);
def_INSTR_TAB("??? 011 ? ????? ????? ??? ????? ????? ??", vldxu);
def_INSTR_TAB("??? 100 ? ????? ????? ??? ????? ????? ??", vldus);
def_INSTR_TAB("??? 110 ? ????? ????? ??? ????? ????? ??", vldss);
def_INSTR_TAB("??? 111 ? ????? ????? ??? ????? ????? ??", vldxs);
return EXEC_ID_inv;
}
def_THelper(vstore) {
def_INSTR_TAB("??? 000 ? ????? ????? ??? ????? ????? ??", vstu);
def_INSTR_TAB("??? 010 ? ????? ????? ??? ????? ????? ??", vsts);
def_INSTR_TAB("??? 011 ? ????? ????? ??? ????? ????? ??", vstx);
def_INSTR_TAB("??? 111 ? ????? ????? ??? ????? ????? ??", vstxu);
return EXEC_ID_inv;
}
def_THelper(vload_mmu) {
def_INSTR_TAB("??? 000 ? ????? ????? ??? ????? ????? ??", vlduu_mmu);
def_INSTR_TAB("??? 010 ? ????? ????? ??? ????? ????? ??", vldsu_mmu);
def_INSTR_TAB("??? 011 ? ????? ????? ??? ????? ????? ??", vldxu_mmu);
def_INSTR_TAB("??? 100 ? ????? ????? ??? ????? ????? ??", vldus_mmu);
def_INSTR_TAB("??? 110 ? ????? ????? ??? ????? ????? ??", vldss_mmu);
def_INSTR_TAB("??? 111 ? ????? ????? ??? ????? ????? ??", vldxs_mmu);
return EXEC_ID_inv;
}
def_THelper(vstore_mmu) {
def_INSTR_TAB("??? 000 ? ????? ????? ??? ????? ????? ??", vstu_mmu);
def_INSTR_TAB("??? 010 ? ????? ????? ??? ????? ????? ??", vsts_mmu);
def_INSTR_TAB("??? 011 ? ????? ????? ??? ????? ????? ??", vstx_mmu);
def_INSTR_TAB("??? 111 ? ????? ????? ??? ????? ????? ??", vstxu_mmu);
return EXEC_ID_inv;
}
#endif
def_THelper(fload) {
if (!fp_enable()) return table_rt_inv(s);
print_Dop(id_src1->str, OP_STR_SIZE, "%ld(%s)", id_src2->imm, reg_name(s->isa.instr.i.rs1, 4));
#ifdef CONFIG_RVV_010
const int table [8] = {1, 0, 0, 0, 0, 2, 4, 0};
s->vm = s->isa.instr.v_opv1.v_vm; //1 for without mask; 0 for with mask
s->v_width = table[s->isa.instr.vldfp.v_width];
#endif // CONFIG_RVV_010
int mmu_mode = isa_mmu_state();
if (mmu_mode == MMU_DIRECT) {
def_INSTR_TAB("??????? ????? ????? 010 ????? ????? ??", flw);
def_INSTR_TAB("??????? ????? ????? 011 ????? ????? ??", fld);
if (fp_enable()) {
def_INSTR_TAB("??????? ????? ????? 010 ????? ????? ??", flw);
def_INSTR_TAB("??????? ????? ????? 011 ????? ????? ??", fld);
}
#ifdef CONFIG_RVV_010
if (vp_enable()) {
def_INSTR_TAB("??????? ????? ????? 000 ????? ????? ??", vload);
def_INSTR_TAB("??????? ????? ????? 101 ????? ????? ??", vload);
def_INSTR_TAB("??????? ????? ????? 110 ????? ????? ??", vload);
}
#endif // CONFIG_RVV_010
} else if (mmu_mode == MMU_TRANSLATE) {
def_INSTR_TAB("??????? ????? ????? 010 ????? ????? ??", flw_mmu);
def_INSTR_TAB("??????? ????? ????? 011 ????? ????? ??", fld_mmu);
if (fp_enable()) {
def_INSTR_TAB("??????? ????? ????? 010 ????? ????? ??", flw_mmu);
def_INSTR_TAB("??????? ????? ????? 011 ????? ????? ??", fld_mmu);
}
#ifdef CONFIG_RVV_010
if (vp_enable()) {
def_INSTR_TAB("??????? ????? ????? 000 ????? ????? ??", vload_mmu);
def_INSTR_TAB("??????? ????? ????? 101 ????? ????? ??", vload_mmu);
def_INSTR_TAB("??????? ????? ????? 110 ????? ????? ??", vload_mmu);
}
#endif // CONFIG_RVV_010
} else { assert(0); }
return EXEC_ID_inv;
}
def_THelper(fstore) {
if (!fp_enable()) return table_rt_inv(s);
print_Dop(id_src1->str, OP_STR_SIZE, "%ld(%s)", id_src2->imm, reg_name(s->isa.instr.i.rs1, 4));
#ifdef CONFIG_RVV_010
const int table [8] = {1, 0, 0, 0, 0, 2, 4, 0};
s->vm = s->isa.instr.v_opv1.v_vm; //1 for without mask; 0 for with mask
s->v_width = table[s->isa.instr.vldfp.v_width];
#endif // CONFIG_RVV_010
int mmu_mode = isa_mmu_state();
if (mmu_mode == MMU_DIRECT) {
def_INSTR_TAB("??????? ????? ????? 010 ????? ????? ??", fsw);
def_INSTR_TAB("??????? ????? ????? 011 ????? ????? ??", fsd);
if (fp_enable()) {
def_INSTR_TAB("??????? ????? ????? 010 ????? ????? ??", fsw);
def_INSTR_TAB("??????? ????? ????? 011 ????? ????? ??", fsd);
}
#ifdef CONFIG_RVV_010
if (vp_enable()) {
def_INSTR_TAB("??????? ????? ????? 000 ????? ????? ??", vstore);
def_INSTR_TAB("??????? ????? ????? 101 ????? ????? ??", vstore);
def_INSTR_TAB("??????? ????? ????? 110 ????? ????? ??", vstore);
}
#endif // CONFIG_RVV_010
} else if (mmu_mode == MMU_TRANSLATE) {
def_INSTR_TAB("??????? ????? ????? 010 ????? ????? ??", fsw_mmu);
def_INSTR_TAB("??????? ????? ????? 011 ????? ????? ??", fsd_mmu);
if (fp_enable()) {
def_INSTR_TAB("??????? ????? ????? 010 ????? ????? ??", fsw_mmu);
def_INSTR_TAB("??????? ????? ????? 011 ????? ????? ??", fsd_mmu);
}
#ifdef CONFIG_RVV_010
if (vp_enable()) {
def_INSTR_TAB("??????? ????? ????? 000 ????? ????? ??", vstore_mmu);
def_INSTR_TAB("??????? ????? ????? 101 ????? ????? ??", vstore_mmu);
def_INSTR_TAB("??????? ????? ????? 110 ????? ????? ??", vstore_mmu);
}
#endif // CONFIG_RVV_010
} else { assert(0); }
return EXEC_ID_inv;
}
......
......@@ -11,6 +11,9 @@ static inline def_DopHelper(r) {
static word_t zero_null = 0;
op->preg = (!load_val && val == 0) ? &zero_null : &reg_l(val);
print_Dop(op->str, OP_STR_SIZE, "%s", reg_name(val, 4));
#ifdef CONFIG_RVV_010
op->reg = val;
#endif // CONFIG_RVV_010
}
static inline def_DHelper(I) {
......
#ifdef CONFIG_RVV_010
// vector
static inline def_DHelper(OP_V) { // 10_101, same to R
decode_op_r(s, id_src1, s->isa.instr.r.rs1, true);
decode_op_r(s, id_src2, s->isa.instr.r.rs2, true);
decode_op_r(s, id_dest, s->isa.instr.r.rd, false);
// decode_op_r(id_dest, decinfo.isa.instr.v_vd, false);
}
static inline def_DHelper(vsetvl) {
rtl_li(s, &id_src2->val, s->isa.instr.v_opv2.v_bigbit ? id_src2->val : s->isa.instr.v_opv2.v_zimm);
if (s->isa.instr.v_opv2.v_bigbit) {
print_Dop(id_src2->str, OP_STR_SIZE, "%ld", id_src2->val);
} else {
print_Dop(id_src2->str, OP_STR_SIZE, "%ld", s->isa.instr.v_opv2.v_zimm);
}
}
//vector
def_THelper(vopi) {
def_INSTR_TAB("000000 ? ????? ????? ??? ????? ????? ??", vadd);
def_INSTR_TAB("000010 ? ????? ????? ??? ????? ????? ??", vsub);
def_INSTR_TAB("000011 ? ????? ????? ??? ????? ????? ??", vrsub);
def_INSTR_TAB("000100 ? ????? ????? ??? ????? ????? ??", vminu);
def_INSTR_TAB("000101 ? ????? ????? ??? ????? ????? ??", vmin);
def_INSTR_TAB("000110 ? ????? ????? ??? ????? ????? ??", vmaxu);
def_INSTR_TAB("000111 ? ????? ????? ??? ????? ????? ??", vmax);
def_INSTR_TAB("001001 ? ????? ????? ??? ????? ????? ??", vand);
def_INSTR_TAB("001010 ? ????? ????? ??? ????? ????? ??", vor);
def_INSTR_TAB("001011 ? ????? ????? ??? ????? ????? ??", vxor);
def_INSTR_TAB("001100 ? ????? ????? ??? ????? ????? ??", vrgather);
def_INSTR_TAB("001110 ? ????? ????? ??? ????? ????? ??", vslideup);
def_INSTR_TAB("001111 ? ????? ????? ??? ????? ????? ??", vslidedown);
def_INSTR_TAB("010000 ? ????? ????? ??? ????? ????? ??", vadc);
def_INSTR_TAB("010001 ? ????? ????? ??? ????? ????? ??", vmadc);
def_INSTR_TAB("010010 ? ????? ????? ??? ????? ????? ??", vsbc);
def_INSTR_TAB("010011 ? ????? ????? ??? ????? ????? ??", vmsbc);
def_INSTR_TAB("010111 ? ????? ????? ??? ????? ????? ??", vmerge);
def_INSTR_TAB("011000 ? ????? ????? ??? ????? ????? ??", vmseq);
def_INSTR_TAB("011001 ? ????? ????? ??? ????? ????? ??", vmsne);
def_INSTR_TAB("011010 ? ????? ????? ??? ????? ????? ??", vmsltu);
def_INSTR_TAB("011011 ? ????? ????? ??? ????? ????? ??", vmslt);
def_INSTR_TAB("011100 ? ????? ????? ??? ????? ????? ??", vmsleu);
def_INSTR_TAB("011101 ? ????? ????? ??? ????? ????? ??", vmsle);
def_INSTR_TAB("011110 ? ????? ????? ??? ????? ????? ??", vmsgtu);
def_INSTR_TAB("011111 ? ????? ????? ??? ????? ????? ??", vmsgt);
def_INSTR_TAB("100000 ? ????? ????? ??? ????? ????? ??", vsaddu);
def_INSTR_TAB("100001 ? ????? ????? ??? ????? ????? ??", vsadd);
def_INSTR_TAB("100010 ? ????? ????? ??? ????? ????? ??", vssubu);
def_INSTR_TAB("100011 ? ????? ????? ??? ????? ????? ??", vssub);
def_INSTR_TAB("100100 ? ????? ????? ??? ????? ????? ??", vaadd);
def_INSTR_TAB("100101 ? ????? ????? ??? ????? ????? ??", vsll);
def_INSTR_TAB("100110 ? ????? ????? ??? ????? ????? ??", vasub);
def_INSTR_TAB("100111 ? ????? ????? ??? ????? ????? ??", vsmul);
def_INSTR_TAB("101000 ? ????? ????? ??? ????? ????? ??", vsrl);
def_INSTR_TAB("101001 ? ????? ????? ??? ????? ????? ??", vsra);
def_INSTR_TAB("101011 ? ????? ????? ??? ????? ????? ??", vssra);
def_INSTR_TAB("101100 ? ????? ????? ??? ????? ????? ??", vnsrl);
def_INSTR_TAB("101101 ? ????? ????? ??? ????? ????? ??", vnsra);
def_INSTR_TAB("101110 ? ????? ????? ??? ????? ????? ??", vnclipu);
def_INSTR_TAB("101111 ? ????? ????? ??? ????? ????? ??", vnclip);
def_INSTR_TAB("101010 ? ????? ????? ??? ????? ????? ??", vssrl);
def_INSTR_TAB("110000 ? ????? ????? ??? ????? ????? ??", vwredsumu);
def_INSTR_TAB("110001 ? ????? ????? ??? ????? ????? ??", vwredsum);
def_INSTR_TAB("111000 ? ????? ????? ??? ????? ????? ??", vdotu);
def_INSTR_TAB("111001 ? ????? ????? ??? ????? ????? ??", vdot);
def_INSTR_TAB("111100 ? ????? ????? ??? ????? ????? ??", vwsmaccu);
def_INSTR_TAB("111101 ? ????? ????? ??? ????? ????? ??", vwsmacc);
def_INSTR_TAB("111110 ? ????? ????? ??? ????? ????? ??", vwsmaccsu);
def_INSTR_TAB("111111 ? ????? ????? ??? ????? ????? ??", vwsmaccus);
return EXEC_ID_inv;
//longjmp_raise_intr(EX_II);
}
def_THelper(vopm) {
def_INSTR_TAB("000000 ? ????? ????? ??? ????? ????? ??", vredsum);
def_INSTR_TAB("000001 ? ????? ????? ??? ????? ????? ??", vredand);
def_INSTR_TAB("000010 ? ????? ????? ??? ????? ????? ??", vredor);
def_INSTR_TAB("000011 ? ????? ????? ??? ????? ????? ??", vredxor);
def_INSTR_TAB("000100 ? ????? ????? ??? ????? ????? ??", vredminu);
def_INSTR_TAB("000101 ? ????? ????? ??? ????? ????? ??", vredmin);
def_INSTR_TAB("000110 ? ????? ????? ??? ????? ????? ??", vredmaxu);
def_INSTR_TAB("000111 ? ????? ????? ??? ????? ????? ??", vredmax);
def_INSTR_TAB("010100 ? ????? ????? ??? ????? ????? ??", vmpopc);
def_INSTR_TAB("010101 ? ????? ????? ??? ????? ????? ??", vmfirst);
def_INSTR_TAB("010110 ? ????? ????? ??? ????? ????? ??", vmunaryo);
def_INSTR_TAB("010111 ? ????? ????? ??? ????? ????? ??", vcompress);
def_INSTR_TAB("011000 ? ????? ????? ??? ????? ????? ??", vmandnot);
def_INSTR_TAB("011001 ? ????? ????? ??? ????? ????? ??", vmand);
def_INSTR_TAB("011010 ? ????? ????? ??? ????? ????? ??", vmor);
def_INSTR_TAB("011011 ? ????? ????? ??? ????? ????? ??", vmxor);
def_INSTR_TAB("011100 ? ????? ????? ??? ????? ????? ??", vmornot);
def_INSTR_TAB("011101 ? ????? ????? ??? ????? ????? ??", vmnand);
def_INSTR_TAB("011110 ? ????? ????? ??? ????? ????? ??", vmnor);
def_INSTR_TAB("011111 ? ????? ????? ??? ????? ????? ??", vmxnor);
def_INSTR_TAB("100000 ? ????? ????? ??? ????? ????? ??", vdivu);
def_INSTR_TAB("100001 ? ????? ????? ??? ????? ????? ??", vdiv);
def_INSTR_TAB("100010 ? ????? ????? ??? ????? ????? ??", vremu);
def_INSTR_TAB("100011 ? ????? ????? ??? ????? ????? ??", vrem);
def_INSTR_TAB("100100 ? ????? ????? ??? ????? ????? ??", vmulhu);
def_INSTR_TAB("100101 ? ????? ????? ??? ????? ????? ??", vmul);
def_INSTR_TAB("100110 ? ????? ????? ??? ????? ????? ??", vmulhsu);
def_INSTR_TAB("100111 ? ????? ????? ??? ????? ????? ??", vmulh);
def_INSTR_TAB("101001 ? ????? ????? ??? ????? ????? ??", vmadd);
def_INSTR_TAB("101010 ? ????? ????? ??? ????? ????? ??", vnmsub);
def_INSTR_TAB("101101 ? ????? ????? ??? ????? ????? ??", vmacc);
def_INSTR_TAB("101111 ? ????? ????? ??? ????? ????? ??", vnmsac);
def_INSTR_TAB("110000 ? ????? ????? ??? ????? ????? ??", vwaddu);
def_INSTR_TAB("110001 ? ????? ????? ??? ????? ????? ??", vwadd);
def_INSTR_TAB("110010 ? ????? ????? ??? ????? ????? ??", vwsubu);
def_INSTR_TAB("110011 ? ????? ????? ??? ????? ????? ??", vwsub);
def_INSTR_TAB("110100 ? ????? ????? ??? ????? ????? ??", vwaddu_w);
def_INSTR_TAB("110101 ? ????? ????? ??? ????? ????? ??", vwadd_w);
def_INSTR_TAB("110110 ? ????? ????? ??? ????? ????? ??", vwsubu_w);
def_INSTR_TAB("110111 ? ????? ????? ??? ????? ????? ??", vwsub_w);
def_INSTR_TAB("111000 ? ????? ????? ??? ????? ????? ??", vwmulu);
def_INSTR_TAB("111010 ? ????? ????? ??? ????? ????? ??", vwmulsu);
def_INSTR_TAB("111011 ? ????? ????? ??? ????? ????? ??", vwmul);
def_INSTR_TAB("111100 ? ????? ????? ??? ????? ????? ??", vwmaccu);
def_INSTR_TAB("111101 ? ????? ????? ??? ????? ????? ??", vwnmacc);
def_INSTR_TAB("111110 ? ????? ????? ??? ????? ????? ??", vwmaccsu);
def_INSTR_TAB("111111 ? ????? ????? ??? ????? ????? ??", vwmaccus);
return EXEC_ID_inv;
}
def_THelper(vopf) {
// longjmp_raise_intr(EX_II);
return EXEC_ID_inv;
}
def_THelper(vsetvl_dispatch) {
def_INSTR_TAB("??????? ????? ????? ??? ????? ????? ??", vsetvl);
return EXEC_ID_inv;
}
// All RVV instructions decode start from here
def_THelper(OP_V) { // 10_101
if (!vp_enable()) {
return EXEC_ID_inv;
}
switch (s->isa.instr.i.funct3) {
case 0 : s->src_vmode = SRC_VV; break;
case 1 : s->src_vmode = SRC_VV; break;
case 2 : s->src_vmode = SRC_VV; break;
case 3 : s->src_vmode = SRC_VI; break;
case 4 : s->src_vmode = SRC_VS; break;
case 5 : s->src_vmode = SRC_VS; break;
case 6 : s->src_vmode = SRC_VS; break;
case 7 : s->src_vmode = SRC_SI; break;
}
s->v_width = 1 << vtype->vsew;
s->vm = s->isa.instr.v_opv1.v_vm; //1 for without mask; 0 for with mask
/*
switch(s->isa.instr.i.funct3) {
EX(0x0, vopi) EX(0x1, vopf) EX(0x2, vopm) EX(0x3, vopi) EX(0x4, vopi) EX(0x5, vopf) EX(0x6, vopm) IDEX(0x7, vsetvl, vsetvl)
}
*/
def_INSTR_TAB("??????? ????? ????? 000 ????? ????? ??", vopi);
def_INSTR_TAB("??????? ????? ????? 001 ????? ????? ??", vopf);
def_INSTR_TAB("??????? ????? ????? 010 ????? ????? ??", vopm);
def_INSTR_TAB("??????? ????? ????? 011 ????? ????? ??", vopi);
def_INSTR_TAB("??????? ????? ????? 100 ????? ????? ??", vopi);
def_INSTR_TAB("??????? ????? ????? 101 ????? ????? ??", vopf);
def_INSTR_TAB("??????? ????? ????? 110 ????? ????? ??", vopm);
def_INSTR_IDTAB("??????? ????? ????? 111 ????? ????? ??", vsetvl, vsetvl_dispatch);
return EXEC_ID_inv;
}
#endif // CONFIG_RVV_010
#include "vcfg.h"
#include "vcompute.h"
#include "vldst.h"
#include <common.h>
#ifdef CONFIG_RVV_010
#include "cpu/exec.h"
#include "../local-include/vreg.h"
#include "../local-include/csr.h"
#include <stdio.h>
#include "../local-include/intr.h"
#include "../local-include/rtl.h"
#include <setjmp.h>
#define id_src (&s->src1)
#define id_src2 (&s->src2)
#define id_dest (&s->dest)
void vp_set_dirty();
def_EHelper(vsetvl) {
vp_set_dirty();
//vlmul+lg2(VLEN) <= vsew + vl
// previous decode does not load vals for us
rtl_lr(s, &(id_src->val), id_src1->reg, 4);
rtlreg_t vl = check_vsetvl(id_src2->val, id_src->val, id_src->reg==0);
rtlreg_t error = 1ul << 63;
if(vl==(uint64_t)-1) vcsr_write(IDXVTYPE, &error); //TODO: may cause error.
else vcsr_write(IDXVTYPE, &(id_src2->val));
vcsr_write(IDXVL, &vl);
rtl_sr(s, id_dest->reg, &vl, 8/*4*/);
rtl_li(s, &(s->tmp_reg[0]), 0);
vcsr_write(IDXVSTART, &(s->tmp_reg[0]));
// print_asm_template3(vsetvl);
}
#endif // CONFIG_RVV_010
\ No newline at end of file
#include <common.h>
#ifdef CONFIG_RVV_010
#include "vcompute_impl.h"
// #define PERMInstr(opcode) permutation_instr(opcode, pc);
// static void permutation_instr(int opcode, vaddr_t* pc) {
// // only move/ext here, no slide
// switch (opcode) {
// case EXT_X_V :
// }
// }
def_EHelper(vadd) {
ARTHI(ADD, SIGNED)
// print_asm_template3(vadd);
}
def_EHelper(vsub) {
Assert(s->src_vmode != SRC_VI, "vsub.vi not supported\n");
ARTHI(SUB, SIGNED)
// print_asm_template3(vsub);
}
def_EHelper(vrsub) {
Assert(s->src_vmode != SRC_VV, "vrsub.vv not supported\n");
ARTHI(RSUB, SIGNED)
// print_asm_template3(vrsub);
}
def_EHelper(vminu) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vmin) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vmaxu) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vmax) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vand) {
ARTHI(AND, SIGNED)
// print_asm_template3(vand);
// longjmp_raise_intr(EX_II);
}
def_EHelper(vor) {
ARTHI(OR, SIGNED)
// print_asm_template3(vor);
// longjmp_raise_intr(EX_II);
}
def_EHelper(vxor) {
ARTHI(XOR, SIGNED)
// print_asm_template3(vxor);
// longjmp_raise_intr(EX_II);
}
def_EHelper(vrgather) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vslideup) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vslidedown) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vadc) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vmadc) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vsbc) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vmsbc) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vmerge) {
ARTHI(MERGE, SIGNED)
// print_asm_template3(vmerge);
// longjmp_raise_intr(EX_II);
}
def_EHelper(vmseq) {
ARTHI_COMP(MSEQ, SIGNED)
// print_asm_template3(vmseq);
// longjmp_raise_intr(EX_II);
}
def_EHelper(vmsne) {
ARTHI_COMP(MSNE, SIGNED)
// print_asm_template3(vmsne);
// longjmp_raise_intr(EX_II);
}
def_EHelper(vmsltu) {
Assert(s->src_vmode != SRC_VI, "vmsltu not supprt SRC_VI\n");
ARTHI_COMP(MSLTU, UNSIGNED)
// print_asm_template3(vmsltu);
// longjmp_raise_intr(EX_II);
}
def_EHelper(vmslt) {
Assert(s->src_vmode != SRC_VI, "vmslt not supprt SRC_VI\n");
ARTHI_COMP(MSLT, SIGNED)
// print_asm_template3(vmslt);
// longjmp_raise_intr(EX_II);
}
def_EHelper(vmsleu) {
ARTHI_COMP(MSLEU, UNSIGNED)
// print_asm_template3(vmsleu);
// longjmp_raise_intr(EX_II);
}
def_EHelper(vmsle) {
ARTHI_COMP(MSLE, SIGNED);
// print_asm_template3(vmsle);
// longjmp_raise_intr(EX_II);
}
def_EHelper(vmsgtu) {
Assert(s->src_vmode != SRC_VV, "vmsgtu not support SRC_VV\n");
ARTHI_COMP(MSGTU, UNSIGNED)
// print_asm_template3(vmsgtu);
// longjmp_raise_intr(EX_II);
}
def_EHelper(vmsgt) {
Assert(s->src_vmode != SRC_VV, "vmsgt not support SRC_VV\n");
ARTHI_COMP(MSGT, SIGNED)
// print_asm_template3(vmsgt);
// longjmp_raise_intr(EX_II);
}
def_EHelper(vsaddu) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vsadd) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vssubu) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vssub) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vaadd) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vsll) {
ARTHI(SLL, UNSIGNED)
// print_asm_template3(vsll);
// longjmp_raise_intr(EX_II);
}
def_EHelper(vasub) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vsmul) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vsrl) {
ARTHI(SRL, UNSIGNED)
// print_asm_template3(vsrl);
//longjmp_raise_intr(EX_II);
}
def_EHelper(vsra) {
ARTHI(SRA, UNSIGNED)
// print_asm_template3(vsra);
// longjmp_raise_intr(EX_II);
}
def_EHelper(vssrl) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vssra) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vnsrl) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vnsra) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vnclipu) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vnclip) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vwredsumu) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vwredsum) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vdotu) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vdot) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vwsmaccu) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vwsmacc) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vwsmaccsu) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vwsmaccus) {
longjmp_raise_intr(EX_II);
}
//op-m
def_EHelper(vredsum) {
REDInstr(REDSUM, SIGNED);
// longjmp_raise_intr(EX_II);
}
def_EHelper(vredand) {
REDInstr(REDAND, UNSIGNED);
// longjmp_raise_intr(EX_II);
}
def_EHelper(vredor) {
REDInstr(REDOR, UNSIGNED);
// longjmp_raise_intr(EX_II);
}
def_EHelper(vredxor) {
REDInstr(REDXOR, UNSIGNED);
// longjmp_raise_intr(EX_II);
}
def_EHelper(vredminu) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vredmin) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vredmaxu) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vredmax) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vmpopc) {
// longjmp_raise_intr(EX_II);
if(vstart->val != 0)
longjmp_raise_intr(EX_II);
int vlmax = ((VLEN >> 3) >> vtype->vsew) << vtype->vlmul;
rtl_li(s, s1, 0);
for(int idx = 0; idx < vlmax; idx ++) {
// mask
rtlreg_t mask = get_mask(0, idx, vtype->vsew, vtype->vlmul);
if(s->vm == 0 && mask == 0)
continue;
*s0 = get_mask(id_src2->reg, idx, vtype->vsew, vtype->vlmul);
*s0 &= 1;
if(*s0 == 1)
rtl_addi(s, s1, s1, 1);
}
rtl_sr(s, id_dest->reg, s1, 4);
}
def_EHelper(vmfirst) {
// longjmp_raise_intr(EX_II);
if(vstart->val != 0)
longjmp_raise_intr(EX_II);
int vlmax = ((VLEN >> 3) >> vtype->vsew) << vtype->vlmul;
int idx;
for(idx = 0; idx < vlmax; idx ++) {
*s0 = get_mask(id_src2->reg, idx, vtype->vsew, vtype->vlmul);
*s0 &= 1;
if(*s0 == 1) break;
}
if(idx < vlmax)
rtl_li(s, s1, idx);
else
rtl_li(s, s1, -1);
rtl_sr(s, id_dest->reg, s1, 4);
}
def_EHelper(vmunaryo) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vcompress) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vmandnot) {
MASKINSTR(MANDNOT)
// print_asm_template3(vmandnot);
// longjmp_raise_intr(EX_II);
}
def_EHelper(vmand) {
MASKINSTR(MAND)
// print_asm_template3(vmand);
// longjmp_raise_intr(EX_II);
}
def_EHelper(vmor) {
MASKINSTR(MOR)
// print_asm_template3(vmor);
// longjmp_raise_intr(EX_II);
}
def_EHelper(vmxor) {
MASKINSTR(MXOR)
// print_asm_template3(vmxor);
// longjmp_raise_intr(EX_II);
}
def_EHelper(vmornot) {
MASKINSTR(MORNOT)
// print_asm_template3(vmornot);
// longjmp_raise_intr(EX_II);
}
def_EHelper(vmnand) {
MASKINSTR(MNAND)
// print_asm_template3(vmnand);
// longjmp_raise_intr(EX_II);
}
def_EHelper(vmnor) {
MASKINSTR(MNOR)
// print_asm_template3(vmnor);
// longjmp_raise_intr(EX_II);
}
def_EHelper(vmxnor) {
MASKINSTR(MXNOR);
// print_asm_template3(vmnor);
// longjmp_raise_intr(EX_II);
}
def_EHelper(vdivu) {
Assert(s->src_vmode != SRC_VI, "vdivu does not support SRC_VI\n");
ARTHI(DIVU, UNSIGNED)
// print_asm_template3(vdivu);
// longjmp_raise_intr(EX_II);
}
def_EHelper(vdiv) {
Assert(s->src_vmode != SRC_VI, "vdiv does not support SRC_VI\n");
ARTHI(DIV, SIGNED)
// print_asm_template3(vdiv);
// longjmp_raise_intr(EX_II);
}
def_EHelper(vremu) {
Assert(s->src_vmode != SRC_VI, "vremu does not support SRC_VI\n");
ARTHI(REMU, UNSIGNED)
// print_asm_template3(vremu);
// longjmp_raise_intr(EX_II);
}
def_EHelper(vrem) {
Assert(s->src_vmode != SRC_VI, "vrem does not support SRC_VI\n");
ARTHI(REM, SIGNED)
// print_asm_template3(vrem);
// longjmp_raise_intr(EX_II);
}
def_EHelper(vmulhu) {
Assert(s->src_vmode != SRC_VI, "vmulhu does not support SRC_VI\n");
ARTHI(MULHU, UNSIGNED)
// print_asm_template3(vmulhu);
// longjmp_raise_intr(EX_II);
}
def_EHelper(vmul) {
Assert(s->src_vmode != SRC_VI, "vmul does not support SRC_VI\n");
ARTHI(MUL, SIGNED)
// print_asm_template3(vmul);
// longjmp_raise_intr(EX_II);
}
def_EHelper(vmulhsu) {
Assert(s->src_vmode != SRC_VI, "vmulhsu does not support SRC_VI\n");
ARTHI(MULHSU, UNSIGNED)
// print_asm_template3(vmulshu);
// longjmp_raise_intr(EX_II);
}
def_EHelper(vmulh) {
Assert(s->src_vmode != SRC_VI, "vmulh does not support SRC_VI\n");
ARTHI(MULH, SIGNED)
// print_asm_template3(vmulh);
// longjmp_raise_intr(EX_II);
}
def_EHelper(vmadd) {
ARTHI(MADD, SIGNED)
// print_asm_template3(vmadd);
// longjmp_raise_intr(EX_II);
}
def_EHelper(vnmsub) {
ARTHI(NMSUB, SIGNED)
// print_asm_template3(vnmsub);
// longjmp_raise_intr(EX_II);
}
def_EHelper(vmacc) {
ARTHI(MACC, SIGNED)
// print_asm_template3(vmacc);
// longjmp_raise_intr(EX_II);
}
def_EHelper(vnmsac) {
ARTHI(NMSAC, SIGNED)
// print_asm_template3(vmacc);
// longjmp_raise_intr(EX_II);
}
def_EHelper(vwaddu) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vwadd) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vwsubu) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vwsub) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vwaddu_w) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vwadd_w) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vwsubu_w) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vwsub_w) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vwmulu) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vwmulsu) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vwmul) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vwmaccu) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vwnmacc) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vwmaccsu) {
longjmp_raise_intr(EX_II);
}
def_EHelper(vwmaccus) {
longjmp_raise_intr(EX_II);
}
#endif // CONFIG_RVV_010
\ No newline at end of file
#include <common.h>
#ifdef CONFIG_RVV_010
#include "vcompute_impl.h"
#undef s0
#undef s1
#define s0 (&tmp_reg[0])
#define s1 (&tmp_reg[1])
void arthimetic_instr(int opcode, int is_signed, int dest_reg, Decode *s) {
vp_set_dirty();
int idx;
for(idx = vstart->val; idx < vl->val; idx ++) {
// mask
rtlreg_t mask = get_mask(0, idx, vtype->vsew, vtype->vlmul);
if(s->vm == 0) {
// merge instr will exec no matter mask or not
// masked and mask off exec will left dest unmodified.
if(opcode != MERGE && mask==0) continue;
} else if(opcode == MERGE) {
mask = 1; // merge(mv) get the first operand (s1, rs1, imm);
}
// operand - vs2
get_vreg(id_src2->reg, idx, s0, vtype->vsew, vtype->vlmul, is_signed, 1);
if(is_signed) rtl_sext(s, s0, s0, 1 << vtype->vsew);
// operand - s1 / rs1 / imm
switch (s->src_vmode) {
case SRC_VV :
get_vreg(id_src->reg, idx, s1, vtype->vsew, vtype->vlmul, is_signed, 1);
if(is_signed) rtl_sext(s, s1, s1, 1 << vtype->vsew);
break;
case SRC_VS :
rtl_lr(s, &(id_src->val), id_src1->reg, 4);
rtl_mv(s, s1, &id_src->val);
if(is_signed) rtl_sext(s, s1, s1, 1 << vtype->vsew);
break;
case SRC_VI :
if(is_signed) rtl_li(s, s1, s->isa.instr.v_opv2.v_simm5);
else rtl_li(s, s1, s->isa.instr.v_opv3.v_imm5 );
break;
}
// op
switch (opcode) {
case ADD : rtl_add(s, s1, s0, s1); break;
case SUB : rtl_sub(s, s1, s0, s1); break;
case RSUB: rtl_sub(s, s1, s1, s0); break;
case AND : rtl_and(s, s1, s0, s1); break;
case OR : rtl_or(s, s1, s0, s1); break;
case XOR : rtl_xor(s, s1, s0, s1); break;
case SLL :
rtl_andi(s, s1, s1, s->v_width*8-1); //low lg2(SEW) is valid
//rtl_sext(s0, s0, 8 - (1 << vtype->vsew)); //sext first
rtl_shl(s, s1, s0, s1); break;
case SRL :
rtl_andi(s, s1, s1, s->v_width*8-1); //low lg2(SEW)
rtl_shr(s, s1, s0, s1); break;
case SRA :
rtl_andi(s, s1, s1, s->v_width*8-1); //low lg2(SEW)
rtl_sext(s, s0, s0, s->v_width);
rtl_sar(s, s1, s0, s1); break;
case MULHU :
*s1 = (uint64_t)(((__uint128_t)(*s0) * (__uint128_t)(*s1))>>(s->v_width*8));
break;
case MUL : rtl_mulu_lo(s, s1, s0, s1); break;
case MULHSU :
rtl_sext(s, t0, s0, s->v_width);
rtl_sari(s, t0, t0, s->v_width*8-1);
rtl_and(s, t0, s1, t0);
*s1 = (uint64_t)(((__uint128_t)(*s0) * (__uint128_t)(*s1))>>(s->v_width*8));
rtl_sub(s, s1, s1, t0);
break;
case MULH :
rtl_sext(s, s0, s0, s->v_width);
rtl_sext(s, s1, s1, s->v_width);
*s1 = (uint64_t)(((__int128_t)(sword_t)(*s0) * (__int128_t)(sword_t)(*s1))>>(s->v_width*8));
break;
case MACC :
rtl_mulu_lo(s, s1, s0, s1);
get_vreg(id_dest->reg, idx, s0, vtype->vsew, vtype->vlmul, is_signed, 1);
rtl_add(s, s1, s1, s0);
break;
case NMSAC :
rtl_mulu_lo(s, s1, s0, s1);
get_vreg(id_dest->reg, idx, s0, vtype->vsew, vtype->vlmul, is_signed, 1);
rtl_sub(s, s1, s0, s1);
break;
case MADD :
get_vreg(id_dest->reg, idx, s0, vtype->vsew, vtype->vlmul, is_signed, 1);
rtl_mulu_lo(s, s1, s0, s1);
get_vreg(id_src2->reg, idx, s0, vtype->vsew, vtype->vlmul, is_signed, 1);
rtl_add(s, s1, s1, s0);
break;
case NMSUB :
get_vreg(id_dest->reg, idx, s0, vtype->vsew, vtype->vlmul, is_signed, 1);
rtl_mulu_lo(s, s1, s1, s0);
get_vreg(id_src2->reg, idx, s0, vtype->vsew, vtype->vlmul, is_signed, 1);
rtl_sub(s, s1, s0, s1);
break;
case DIVU :
if(*s1 == 0) rtl_li(s, s1, ~0lu);
else rtl_divu_q(s, s1, s0, s1);
break;
case DIV :
rtl_sext(s, s0, s0, s->v_width);
rtl_sext(s, s1, s1, s->v_width);
if(*s1 == 0) rtl_li(s, s1, ~0lu);
else if(*s0 == 0x8000000000000000LL && *s1 == -1) //may be error
rtl_mv(s, s1, s0);
else rtl_divs_q(s, s1, s0, s1);
break;
case REMU :
if (*s1 == 0) rtl_mv(s, s1, s0);
else rtl_divu_r(s, s1, s0, s1);
break;
case REM :
rtl_sext(s, s0, s0, s->v_width);
rtl_sext(s, s1, s1, s->v_width);
if(*s1 == 0) rtl_mv(s, s1, s0);
else if(*s1 == 0x8000000000000000LL && *s1 == -1) //may be error
rtl_li(s, s1, 0);
else rtl_divs_r(s, s1, s0, s1);
break;
case MERGE : rtl_mux(s, s1, &mask, s1, s0); break;
case MSEQ : rtl_setrelop(s, RELOP_EQ, s1, s0, s1); break;
case MSNE : rtl_setrelop(s, RELOP_NE, s1, s0, s1); break;
case MSLTU : rtl_setrelop(s, RELOP_LTU, s1, s0, s1); break;
case MSLT : rtl_setrelop(s, RELOP_LT, s1, s0, s1); break;
case MSLEU : rtl_setrelop(s, RELOP_LEU, s1, s0, s1); break;
case MSLE : rtl_setrelop(s, RELOP_LE, s1, s0, s1); break;
case MSGTU : rtl_setrelop(s, RELOP_GTU, s1, s0, s1); break;
case MSGT : rtl_setrelop(s, RELOP_GT, s1, s0, s1); break;
}
// store to vrf
if(dest_reg == 1)
set_mask(id_dest->reg, idx, *s1, vtype->vsew, vtype->vlmul);
else
set_vreg(id_dest->reg, idx, *s1, vtype->vsew, vtype->vlmul, 1);
}
// idx gt the vl need to be zeroed.
// int vlmax = ((VLEN >> 3) >> vtype->vsew) << vtype->vlmul;
// for(idx = vl->val; idx < vlmax; idx ++) {
// rtl_li(s1, 0);
// if(dest_reg == 1)
// set_mask(id_dest->reg, idx, s1, vtype->vsew, vtype->vlmul);
// else
// set_vreg(id_dest->reg, idx, s1, vtype->vsew, vtype->vlmul, 1);
// }
// TODO: the idx larger than vl need reset to zero.
rtl_li(s, s0, 0);
vcsr_write(IDXVSTART, s0);
}
void mask_instr(int opcode, Decode *s) {
vp_set_dirty();
int idx;
for(idx = vstart->val; idx < vl->val; idx++) {
// operand - vs2
*s0 = get_mask(id_src2->reg, idx, vtype->vsew, vtype->vlmul); // unproper usage of s0
*s0 &= 1; // only LSB
// operand - s1
*s1 = get_mask(id_src->reg, idx, vtype->vsew, vtype->vlmul); // unproper usage of s1
*s1 &= 1; // only LSB
// op
switch (opcode) {
case MAND : rtl_and(s, s1, s0, s1); break;
case MNAND : rtl_and(s, s1, s0, s1);
*s1 = !(*s1); break;
case MANDNOT : *s1 = !(*s1); // unproper usage of not
rtl_and(s, s1, s0, s1); break;
case MXOR : rtl_xor(s, s1, s0, s1); break;
case MOR : rtl_or(s, s1, s0, s1); break;
case MNOR : rtl_or(s, s1, s0, s1);
*s1 = !(*s1); break;
case MORNOT : *s1 = !(*s1);
rtl_or(s, s1, s0, s1); break;
case MXNOR : rtl_xor(s, s1, s0, s1);
*s1 = !(*s1); break;
default : longjmp_raise_intr(EX_II);
}
// store to vrf
*s1 &= 1; // make sure the LSB
set_mask(id_dest->reg, idx, *s1, vtype->vsew, vtype->vlmul);
}
int vlmax = ((VLEN >> 3) >> vtype->vsew) << vtype->vlmul;
rtl_li(s, s1, 0);
for( idx = vl->val; idx < vlmax; idx++) {
set_mask(id_dest->reg, idx, *s1, vtype->vsew, vtype->vlmul);
}
vcsr_write(IDXVSTART, s1);
}
void reduction_instr(int opcode, int is_signed, Decode *s) {
vp_set_dirty();
// TODO: check here: does not need align??
get_vreg(id_src->reg, 0, s1, vtype->vsew, vtype->vlmul, is_signed, 0);
if(is_signed) rtl_sext(s, s1, s1, 1 << vtype->vsew);
int idx;
for(idx = vstart->val; idx < vl->val; idx ++) {
rtlreg_t mask = get_mask(0, idx, vtype->vsew, vtype->vlmul);
if(s->vm == 0) {
// merge instr will exec no matter mask or not
// masked and mask off exec will left dest unmodified.
if(opcode != MERGE && mask==0) continue;
} else if(opcode == MERGE) {
mask = 1; // merge(mv) get the first operand (s1, rs1, imm);
}
// operand - vs2
get_vreg(id_src2->reg, idx, s0, vtype->vsew, vtype->vlmul, is_signed, 1);
if(is_signed) rtl_sext(s, s0, s0, 1 << vtype->vsew);
// op
switch (opcode) {
case REDSUM : rtl_add(s, s1, s0, s1); break;
case REDOR : rtl_or(s, s1, s0, s1); break;
case REDAND : rtl_and(s, s1, s0, s1); break;
case REDXOR : rtl_xor(s, s1, s0, s1); break;
// case MIN :
// MINU is hard to achieve parallel
}
}
set_vreg(id_dest->reg, 0, *s1, vtype->vsew, vtype->vlmul, 0);
int vlmax = ((VLEN >> 3) >> vtype->vsew);
for(int i=1; i<vlmax; i++) {
set_vreg(id_dest->reg, i, 0, vtype->vsew, vtype->vlmul, 0);
}
}
// dirty job here
#undef s0
#undef s1
#define s0 &ls0
#define s1 &ls1
#endif // CONFIG_RVV_010
\ No newline at end of file
#include <common.h>
#ifdef CONFIG_RVV_010
#ifndef __RISCV64_VCOMPUTE_IMPL_H__
#define __RISCV64_VCOMPUTE_IMPL_H__
#include "cpu/exec.h"
#include "vreg.h"
#include "../local-include/csr.h"
#include <stdio.h>
#include "../local-include/intr.h"
#include "../local-include/rtl.h"
#include <setjmp.h>
#define id_src (&s->src1)
#define id_src2 (&s->src2)
#define id_dest (&s->dest)
enum op_t {
ADD, SUB, RSUB, MINU, MIN, MAXU, MAX, AND,
OR, XOR, RGATHER, SLIDEUP, SLIDEDOWN, ADC, MADC, SBC,
MSBC, MERGE, MSEQ, MSNE, MSLTU, MSLT, MSLEU, MSLE,
MSGTU, MSGT, SADDU, SADD, SSUBU, SSUB, AADD, SLL,
ASUB, SMUL, SRL, SRA, SSRL, SSRA, NSRL, NSRA,
NCLIPU, NCLIP, WREDSUMU, WREDSUM, DOTU, DOT, WSMACCU, WSMACC,
WSMAXXSU, WSMACCUS,
REDSUM, REDAND, REDOR, REDXOR, REDMINU, REDMIN, REDMAXU, REDMAX,
EXT_X_V, MV_S_X, SLIDE1UP, SLIDE1DOWN, MPOPC, VMFIRST, MUNARYO, COMPRESS,
MANDNOT, MAND, MOR, MXOR, MORNOT, MNAND, MNOR, MXNOR,
DIVU, DIV, REMU, REM, MULHU, MUL, MULHSU, MULH,
MADD, NMSUB, MACC, NMSAC, WADDU, WADD, WSUBU, WSUB,
WADDU_W, WADD_W, WSUBU_W, WSUB_W, WMULU, WMULSU, WMUL, WMACCU,
WNMACC, WMACCSU, WMACCUS,
};
void vp_set_dirty();
void arthimetic_instr(int opcode, int is_signed, int dest_reg, Decode *s);
void mask_instr(int opcode, Decode *s);
void reduction_instr(int opcode, int is_signed, Decode *s);
#define ARTHI(opcode, is_signed) arthimetic_instr(opcode, is_signed, 0, s);
#define ARTHI_COMP(opcode, is_signed) arthimetic_instr(opcode, is_signed, 1, s);
#define MASKINSTR(opcode) mask_instr(opcode, s);
#define REDInstr(opcode, is_signed) reduction_instr(opcode, is_signed, s);
#endif // __RISCV64_VCOMPUTE_IMPL_H__
#endif // CONFIG_RVV_010
\ No newline at end of file
#include <common.h>
#ifdef CONFIG_RVV_010
#include "vldst_impl.h"
def_EHelper(vlduu) { //unit-strided
/*
switch (s->v_width) {
case 0 : print_asm_template3(vle.v);
case 1 : print_asm_template3(vlbu.v);
case 2 : print_asm_template3(vlhu.v);
case 4 : print_asm_template3(vlwu.v);
}
*/
VLD(MODE_UNIT, UNSIGNED, s, MMU_DIRECT)
//print_asm_template3(vlduu);
}
def_EHelper(vldsu) { //strided unsigned
/*
switch (s->v_width) {
case 0 : print_asm_template3(vlse.v);
case 1 : print_asm_template3(vlsbu.v);
case 2 : print_asm_template3(vlshu.v);
case 4 : print_asm_template3(vlswu.v);
}*/
VLD(MODE_STRIDED, UNSIGNED, s, MMU_DIRECT)
//print_asm_template3(vldsu);
}
def_EHelper(vldxu) {
/*
switch (s->v_width) {
case 0 : print_asm_template3(vlxe.v);
case 1 : print_asm_template3(vlxbu.v);
case 2 : print_asm_template3(vlxhu.v);
case 4 : print_asm_template3(vlxwu.v);
} */
VLD(MODE_INDEXED, UNSIGNED, s, MMU_DIRECT)
//print_asm_template3(vldxu);
}
def_EHelper(vldus) {
/*
switch (s->v_width) {
case 0 : print_asm_template3(vle.v);
case 1 : print_asm_template3(vlb.v);
case 2 : print_asm_template3(vlh.v);
case 4 : print_asm_template3(vlw.v);
}*/
VLD(MODE_UNIT, SIGNED, s, MMU_DIRECT)
//print_asm_template3(vldus);
}
def_EHelper(vldss) {
/*
switch (s->v_width) {
case 0 : print_asm_template3(vlse.v);
case 1 : print_asm_template3(vlsb.v);
case 2 : print_asm_template3(vlsh.v);
case 4 : print_asm_template3(vlsw.v);
}*/
VLD(MODE_STRIDED, SIGNED, s, MMU_DIRECT)
//print_asm_template3(vldss);
}
def_EHelper(vldxs) {
/*
switch (s->v_width) {
case 0 : print_asm_template3(vlxe.v);
case 1 : print_asm_template3(vlxb.v);
case 2 : print_asm_template3(vlxh.v);
case 4 : print_asm_template3(vlxw.v);
}*/
VLD(MODE_INDEXED, SIGNED, s, MMU_DIRECT)
//print_asm_template3(vldxs);
}
def_EHelper(vstu) {
/*
switch (s->v_width) {
case 0 : print_asm_template3(vse.v);
case 1 : print_asm_template3(vsb.v);
case 2 : print_asm_template3(vsh.v);
case 4 : print_asm_template3(vsw.v);
}*/
VST(MODE_UNIT, MMU_DIRECT)
//print_asm_template3(vstu);
}
def_EHelper(vsts) {
/*
switch (s->v_width) {
case 0 : print_asm_template3(vsse.v);
case 1 : print_asm_template3(vssb.v);
case 2 : print_asm_template3(vssh.v);
case 4 : print_asm_template3(vssw.v);
}*/
VST(MODE_STRIDED, MMU_DIRECT)
//print_asm_template3(vsts);
}
def_EHelper(vstx) {
/*
switch (s->v_width) {
case 0 : print_asm_template3(vsxe.v);
case 1 : print_asm_template3(vsxb.v);
case 2 : print_asm_template3(vsxh.v);
case 4 : print_asm_template3(vsxw.v);
}*/
VST(MODE_INDEXED, MMU_DIRECT)
//print_asm_template3(vstx);
}
def_EHelper(vstxu) {
/*
switch (s->v_width) {
case 0 : print_asm_template3(vsuxe.v);
case 1 : print_asm_template3(vsuxb.v);
case 2 : print_asm_template3(vsuxh.v);
case 4 : print_asm_template3(vsuxw.v);
}*/
VST(MODE_INDEXED, MMU_DIRECT)
//print_asm_template3(vstxu);
}
def_EHelper(vlduu_mmu) { //unit-strided
/*
switch (s->v_width) {
case 0 : print_asm_template3(vle.v);
case 1 : print_asm_template3(vlbu.v);
case 2 : print_asm_template3(vlhu.v);
case 4 : print_asm_template3(vlwu.v);
}
*/
VLD(MODE_UNIT, UNSIGNED, s, MMU_TRANSLATE)
//print_asm_template3(vlduu);
}
def_EHelper(vldsu_mmu) { //strided unsigned
/*
switch (s->v_width) {
case 0 : print_asm_template3(vlse.v);
case 1 : print_asm_template3(vlsbu.v);
case 2 : print_asm_template3(vlshu.v);
case 4 : print_asm_template3(vlswu.v);
}*/
VLD(MODE_STRIDED, UNSIGNED, s, MMU_TRANSLATE)
//print_asm_template3(vldsu);
}
def_EHelper(vldxu_mmu) {
/*
switch (s->v_width) {
case 0 : print_asm_template3(vlxe.v);
case 1 : print_asm_template3(vlxbu.v);
case 2 : print_asm_template3(vlxhu.v);
case 4 : print_asm_template3(vlxwu.v);
} */
VLD(MODE_INDEXED, UNSIGNED, s, MMU_TRANSLATE)
//print_asm_template3(vldxu);
}
def_EHelper(vldus_mmu) {
/*
switch (s->v_width) {
case 0 : print_asm_template3(vle.v);
case 1 : print_asm_template3(vlb.v);
case 2 : print_asm_template3(vlh.v);
case 4 : print_asm_template3(vlw.v);
}*/
VLD(MODE_UNIT, SIGNED, s, MMU_TRANSLATE)
//print_asm_template3(vldus);
}
def_EHelper(vldss_mmu) {
/*
switch (s->v_width) {
case 0 : print_asm_template3(vlse.v);
case 1 : print_asm_template3(vlsb.v);
case 2 : print_asm_template3(vlsh.v);
case 4 : print_asm_template3(vlsw.v);
}*/
VLD(MODE_STRIDED, SIGNED, s, MMU_TRANSLATE)
//print_asm_template3(vldss);
}
def_EHelper(vldxs_mmu) {
/*
switch (s->v_width) {
case 0 : print_asm_template3(vlxe.v);
case 1 : print_asm_template3(vlxb.v);
case 2 : print_asm_template3(vlxh.v);
case 4 : print_asm_template3(vlxw.v);
}*/
VLD(MODE_INDEXED, SIGNED, s, MMU_TRANSLATE)
//print_asm_template3(vldxs);
}
def_EHelper(vstu_mmu) {
/*
switch (s->v_width) {
case 0 : print_asm_template3(vse.v);
case 1 : print_asm_template3(vsb.v);
case 2 : print_asm_template3(vsh.v);
case 4 : print_asm_template3(vsw.v);
}*/
VST(MODE_UNIT, MMU_TRANSLATE)
//print_asm_template3(vstu);
}
def_EHelper(vsts_mmu) {
/*
switch (s->v_width) {
case 0 : print_asm_template3(vsse.v);
case 1 : print_asm_template3(vssb.v);
case 2 : print_asm_template3(vssh.v);
case 4 : print_asm_template3(vssw.v);
}*/
VST(MODE_STRIDED, MMU_TRANSLATE)
//print_asm_template3(vsts);
}
def_EHelper(vstx_mmu) {
/*
switch (s->v_width) {
case 0 : print_asm_template3(vsxe.v);
case 1 : print_asm_template3(vsxb.v);
case 2 : print_asm_template3(vsxh.v);
case 4 : print_asm_template3(vsxw.v);
}*/
VST(MODE_INDEXED, MMU_TRANSLATE)
//print_asm_template3(vstx);
}
def_EHelper(vstxu_mmu) {
/*
switch (s->v_width) {
case 0 : print_asm_template3(vsuxe.v);
case 1 : print_asm_template3(vsuxb.v);
case 2 : print_asm_template3(vsuxh.v);
case 4 : print_asm_template3(vsuxw.v);
}*/
VST(MODE_INDEXED, MMU_TRANSLATE)
//print_asm_template3(vstxu);
}
#endif // CONFIG_RVV_010
\ No newline at end of file
#include <common.h>
#ifdef CONFIG_RVV_010
#include "vldst_impl.h"
void vp_set_dirty();
void vld(int mode, int is_signed, Decode *s, int mmu_mode) {
vp_set_dirty();
//TODO: raise instr when decinfo.v_width > SEW
//v_width 0 -> none SEW 0 -> 8
// 1 -> 8 1 -> 16
// 2 -> 16 2 -> 32
// 4 -> 32 3 -> 64
s->v_width = s->v_width == 0 ? 1 << vtype->vsew : s->v_width;
bool error = (s->v_width * 8) > (8 << vtype->vsew);
if(error) {
printf("vld encounter an instr: v_width > SEW: mode::%d is_signed:%d\n", mode, is_signed);
longjmp_raise_intr(EX_II);
}
// previous decode does not load vals for us
rtl_lr(s, &(s->src1.val), s->src1.reg, 4);
word_t idx;
rtl_mv(s, &(tmp_reg[0]), &(s->src1.val));
for(idx = vstart->val; idx < vl->val; idx ++) {
//TODO: SEW now only supports LE 64bit
//TODO: need special rtl function, but here ignore it
if(mode == MODE_INDEXED) {
rtl_mv(s, &(tmp_reg[0]), &(s->src1.val));
get_vreg(id_src2->reg, idx, &tmp_reg[3], vtype->vsew, vtype->vlmul, 1, 1);
rtl_add(s, &tmp_reg[0], &tmp_reg[0], &tmp_reg[3]);
}
// mask
rtlreg_t mask = get_mask(0, idx, vtype->vsew, vtype->vlmul);
// op
if(s->vm != 0 || mask != 0) {
rtl_lm(s, &tmp_reg[1], &tmp_reg[0], 0, s->v_width, mmu_mode);
if (is_signed) rtl_sext(s, &tmp_reg[1], &tmp_reg[1], s->v_width);
set_vreg(id_dest->reg, idx, *&tmp_reg[1], vtype->vsew, vtype->vlmul, 1);
}
switch (mode) {
case MODE_UNIT : rtl_addi(s, &tmp_reg[0], &tmp_reg[0], s->v_width); break;
case MODE_STRIDED: rtl_add(s, &tmp_reg[0], &tmp_reg[0], &id_src2->val) ; break;
}
}
// TODO: the idx larger than vl need reset to zero.
rtl_li(s, &tmp_reg[0], 0);
vcsr_write(IDXVSTART, &tmp_reg[0]);
}
void vst(int mode, Decode *s, int mmu_mode) {
vp_set_dirty();
//TODO: raise instr when decinfo.v_width > SEW
//v_width 0 -> none SEW 0 -> 8
// 1 -> 8 1 -> 16
// 2 -> 16 2 -> 32
// 4 -> 32 3 -> 64
s->v_width = s->v_width == 0 ? 1 << vtype->vsew : s->v_width;
bool error = (s->v_width * 8) < (8 << vtype->vsew);
if(error) {
printf("vst encounter an instr: v_width < SEW: mode::%d\n", mode);
longjmp_raise_intr(EX_II);
}
word_t idx;
rtl_mv(s, &tmp_reg[0], &id_src->val);
for(idx = vstart->val; idx < vl->val; idx ++) {
//TODO: SEW now only supports LE 64bit
//TODO: need special rtl function, but here ignore it
if(mode == MODE_INDEXED) {
rtl_mv(s, &tmp_reg[0], &id_src->val);
get_vreg(id_src2->reg, idx, &tmp_reg[3], vtype->vsew, vtype->vlmul, 1, 1);
rtl_add(s, &tmp_reg[0], &tmp_reg[0], &tmp_reg[3]);
// switch(vtype->vsew) {
// case 0 : rtl_addi(&&tmp_reg[0], &&tmp_reg[0], vreg_b(id_src2->reg, idx)); break;
// case 1 : rtl_addi(&&tmp_reg[0], &&tmp_reg[0], vreg_s(id_src2->reg, idx)); break;
// case 2 : rtl_addi(&&tmp_reg[0], &&tmp_reg[0], vreg_i(id_src2->reg, idx)); break;
// case 3 : rtl_addi(&&tmp_reg[0], &&tmp_reg[0], vreg_l(id_src2->reg, idx)); break;
// }
}
// mask
// uint8_t mask;
// switch (vtype->vsew) {
// case 0 : mask = (uint8_t)(vreg_b(0, idx) & 0x1); break;
// case 1 : mask = (uint8_t)(vreg_s(0, idx) & 0x1); break;
// case 2 : mask = (uint8_t)(vreg_i(0, idx) & 0x1); break;
// case 3 : mask = (uint8_t)(vreg_l(0, idx) & 0x1); break;
// default: mask = 0;
// }
rtlreg_t mask = get_mask(0, idx, vtype->vsew, vtype->vlmul);
// op
if(s->vm != 0 || mask != 0) {
// switch (vtype->vsew) {
// case 0 : rtl_li(&&tmp_reg[1], vreg_b(id_dest->reg, idx)); break;
// case 1 : rtl_li(&&tmp_reg[1], vreg_s(id_dest->reg, idx)); break;
// case 2 : rtl_li(&&tmp_reg[1], vreg_i(id_dest->reg, idx)); break;
// case 3 : rtl_li(&&tmp_reg[1], vreg_l(id_dest->reg, idx)); break;
// }
get_vreg(id_dest->reg, idx, &tmp_reg[1], vtype->vsew, vtype->vlmul, 0, 1);
rtl_sm(s, &tmp_reg[0], &tmp_reg[1], 0, s->v_width, mmu_mode);
}
switch (mode) {
case MODE_UNIT : rtl_addi(s, &tmp_reg[0], &tmp_reg[0], s->v_width); break;
case MODE_STRIDED: rtl_add(s, &tmp_reg[0], &tmp_reg[0], &id_src2->val) ; break;
}
}
// TODO: the idx larger than vl need reset to zero.
vstart->val = 0;
}
#endif // CONFIG_RVV_010
\ No newline at end of file
#include <common.h>
#ifdef CONFIG_RVV_010
#ifndef __RISCV64_VLDST_IMPL_H__
#define __RISCV64_VLDST_IMPL_H__
#include "cpu/exec.h"
#include "vreg.h"
#include "../local-include/csr.h"
#include "../local-include/rtl.h"
#include <stdio.h>
#include "../local-include/intr.h"
#include <setjmp.h>
#define id_src (&s->src1)
#define id_src2 (&s->src2)
#define id_dest (&s->dest)
// vector load
#define MODE_UNIT 0
#define MODE_STRIDED 1
#define MODE_INDEXED 2
#define VLD(mode, is_signed, s, mmu_mode) vld(mode, is_signed, s, mmu_mode);
void vld(int mode, int is_signed, Decode *s, int mmu_mode);
// vector store
#define VST(mode, mmu_mode) vst(mode, s, mmu_mode);
void vst(int mode, Decode *s, int mmu_mode);
#endif // __RISCV64_VLDST_IMPL_H__
#endif // CONFIG_RVV_010
\ No newline at end of file
#include <common.h>
#ifdef CONFIG_RVV_010
#ifndef __RISCV64_VREG_H__
#define __RISCV64_VREG_H__
#include "common.h"
#define VLEN 256
#define VLENLG 8
#define MAXELEN 64
#define VENUM64 (VLEN/64)
#define VENUM32 (VLEN/32)
#define VENUM16 (VLEN/16)
#define VENUM8 (VLEN/8)
#define SLEN 256
static inline int check_reg_index1(int index) {
assert(index >= 0 && index < 32);
return index;
}
static inline int check_reg_index2(int index2, int elen) {
assert(index2 >= 0 && index2 < VLEN/elen);
return index2;
}
// #define vreg_len(index1, index2, elen) (cpu.vr[check_reg_index1(index1)]._64[check_reg_index2(index2, elen)])
#define vreg_ll(index) (cpu.vr[check_reg_index1(index)])
// #define vreg_l(index1, index2) vreg_len(index1, index2, 64)
// #define vreg_i(index1, index2) vreg_len(index1, index2, 32)
// #define vreg_s(index1, index2) vreg_len(index1, index2, 16)
// #define vreg_b(index1, index2) vreg_len(index1, index2, 8)
#define vreg_l(index1, index2) (cpu.vr[check_reg_index1(index1)]._64[check_reg_index2(index2, 64)])
#define vreg_i(index1, index2) (cpu.vr[check_reg_index1(index1)]._32[check_reg_index2(index2, 32)])
#define vreg_s(index1, index2) (cpu.vr[check_reg_index1(index1)]._16[check_reg_index2(index2, 16)])
#define vreg_b(index1, index2) (cpu.vr[check_reg_index1(index1)]._8[check_reg_index2(index2, 8)])
rtlreg_t get_mask(int reg, int idx, uint64_t vsew, uint64_t vlmul);
static inline const char * vreg_name(int index, int width) {
extern const char * vregsl[];
assert(index >= 0 && index < 32);
return vregsl[index];
}
void get_vreg(uint64_t reg, int idx, rtlreg_t *dst, uint64_t vsew, uint64_t vlmul, int is_signed, int needAlign);
void set_vreg(uint64_t reg, int idx, rtlreg_t src, uint64_t vsew, uint64_t vlmul, int needAlgin);
void longjmp_raise_intr(uint32_t foo);
#define SRC_VV 0
#define SRC_VI 1
#define SRC_VS 2
#define SRC_SI 3
#define UNSIGNED 0
#define SIGNED 1
void vcsr_write(uint32_t addr, rtlreg_t *src);
#endif //__RISCV64_VREG_H__
#endif // CONFIG_RVV_010
\ No newline at end of file
#include <common.h>
#ifdef CONFIG_RVV_010
#include "vreg.h"
#include "../local-include/csr.h"
#include <stdio.h>
#include "isa.h"
const char * vregsl[] = {
"v0 ", "v1 ", "v2 ", "v3 ", "v4 ", "v5 ", "v6 ", "v7 ",
"v8 ", "v9 ", "v10", "v11", "v12", "v13", "v14", "v15",
"v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
"v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
};
rtlreg_t check_vsetvl(rtlreg_t vtype_req, rtlreg_t vl_req, bool max_req) {
vtype_t vt = (vtype_t )vtype_req;
rtlreg_t vl_group = ((VLEN >> 3) >> vt.vsew) << vt.vlmul;
if(max_req == true) {
return vl_group;
}else if(vt.vsew > 3) { //check if max-len supported
return (uint64_t)-1; //return 0 means error, including vl_req is 0, for vl_req should not be 0.
}else
return vl_req <= vl_group ? vl_req : vl_group;
// if(vl_group >= vl_req) {
// return vl_req;
// } else if(vl_req >= 2 * vl_group) {
// return vl_group;
// } else {
// return vl_req / 2 + 1;
// }
}
rtlreg_t get_mask(int reg, int idx, uint64_t vsew, uint64_t vlmul) {
// int sum = VLEN / ((1 << vsew) * 8) * vlmul;
int sum = ((VLEN >> vsew) >> 3) << vlmul;
int single = VLEN / sum; //(1 << vsew * 8) / vlmul;
int bit_idx = idx * single;
int idx1 = bit_idx / 64;
int idx2 = bit_idx % 64;
return (rtlreg_t)((cpu.vr[reg]._64[idx1] & (1lu << idx2)) != 0);
}
void set_mask(uint32_t reg, int idx, uint64_t mask, uint64_t vsew, uint64_t vlmul) {
int sum = ((VLEN >> vsew) >> 3) << vlmul;
int single = VLEN / sum; //(1 << vsew * 8) / vlmul;
int bit_idx = idx * single;
int idx1 = bit_idx / 64;
int idx2 = bit_idx % 64;
uint64_t clear_bit = 0;
for(int i=0; i < single; i++) {
clear_bit = clear_bit << 1;
clear_bit |= 1;
} // get single-bit 1-string
cpu.vr[(int)reg]._64[idx1] &= ~(clear_bit << idx2); // clear the dest position.
cpu.vr[(int)reg]._64[idx1] |= (mask==0) ? 0 : (1lu << idx2);
}
void get_vreg(uint64_t reg, int idx, rtlreg_t *dst, uint64_t vsew, uint64_t vlmul, int is_signed, int needAlign) {
Assert(vlmul <= 3, "vlmul should be less than 4\n");
Assert(vsew <= 3, "vsew should be less than 4\n");
if(needAlign) Assert(reg % (1 << vlmul) == 0, "vreg is not aligned\n");
int new_vlmul = 1 << vlmul;
int width = (1 << vsew);
int width_bit = width * 8;
int new_reg = reg + (idx * width_bit) / SLEN % new_vlmul;
int new_idx = (idx * width_bit) / (SLEN * new_vlmul) * (SLEN / width_bit)
+ idx % (SLEN / width_bit);
switch (vsew) {
case 0 : *dst = is_signed ? (char)vreg_b(new_reg, new_idx) : vreg_b(new_reg, new_idx); break;
case 1 : *dst = is_signed ? (short)vreg_s(new_reg, new_idx) : vreg_s(new_reg, new_idx); break;
case 2 : *dst = is_signed ? (int)vreg_i(new_reg, new_idx) : vreg_i(new_reg, new_idx); break;
case 3 : *dst = is_signed ? (long)vreg_l(new_reg, new_idx) : vreg_l(new_reg, new_idx); break;
}
// printf("get_vreg: idx:%d reg:%lu new_idx:%d new_reg:%d vsew:%lu vlmul:%lu\n",
// idx, reg, new_idx, new_reg, vsew, vlmul);
}
void set_vreg(uint64_t reg, int idx, rtlreg_t src, uint64_t vsew, uint64_t vlmul, int needAlign) {
Assert(vlmul <= 3, "vlmul should be less than 4\n");
Assert(vsew <= 3, "vsew should be less than 4\n");
if(needAlign) Assert(reg % (1 << vlmul) == 0, "vreg is not aligned\n");
int new_vlmul = 1 << vlmul;
int width = (1 << vsew);
int width_bit = width * 8;
int new_reg = reg + (idx * width_bit) / SLEN % new_vlmul;
int new_idx = (idx * width_bit) / (SLEN * new_vlmul) * (SLEN / width_bit)
+ idx % (SLEN / width_bit);
switch (vtype->vsew) {
case 0 : vreg_b(new_reg, new_idx) = (uint8_t )src; break;
case 1 : vreg_s(new_reg, new_idx) = (uint16_t )src; break;
case 2 : vreg_i(new_reg, new_idx) = (uint32_t )src; break;
case 3 : vreg_l(new_reg, new_idx) = (uint64_t )src; break;
}
// printf("set_vreg: idx:%d reg:%lu new_idx:%d new_reg:%d vsew:%lu vlmul:%lu\n",
// idx, reg, new_idx, new_reg, vsew, vlmul);
}
void longjmp_raise_intr(uint32_t foo) {
assert(0);
}
#endif // CONFIG_RVV_010
\ No newline at end of file
#include <common.h>
#ifdef CONFIG_RVV_010
#include "../local-include/csr.h"
#include "../local-include/intr.h"
#include <cpu/cpu.h>
bool vp_enable() {
return MUXDEF(CONFIG_MODE_USER, true, mstatus->vs != 0);
}
void vp_set_dirty() {
// lazily update
mstatus->vs = 3;
}
#endif // CONFIG_RVV_010
\ No newline at end of file
......@@ -37,6 +37,15 @@
f(fflags , 0x001) f(frm , 0x002) f(fcsr , 0x003)
#endif
#ifdef CONFIG_RVV_010
#define VCSRS(f) \
f(vstart, 0x008) \
f(vxsat, 0x009) \
f(vxrm, 0x00a) \
f(vl, 0xc20) \
f(vtype, 0xc21)
#endif
#define CSR_STRUCT_START(name) \
typedef union { \
struct {
......@@ -56,7 +65,7 @@ CSR_STRUCT_START(mstatus)
uint64_t pad1: 1;
uint64_t mpie: 1;
uint64_t spp : 1;
uint64_t pad2: 2;
uint64_t vs: 2;
uint64_t mpp : 2;
uint64_t fs : 2;
uint64_t xs : 2;
......@@ -242,8 +251,49 @@ CSR_STRUCT_END(fcsr)
CSR_STRUCT_START(mtime)
CSR_STRUCT_END(mtime)
#ifdef CONFIG_RVV_010
// TODO: implement these vcsr
#define IDXVSTART 0x008
#define IDXVXSAT 0x009
#define IDXVXRM 0x00a
#define IDXVL 0xc20
#define IDXVTYPE 0xc21
CSR_STRUCT_START(vstart)
CSR_STRUCT_END(vstart)
CSR_STRUCT_START(vxsat)
uint64_t sat : 1;
uint64_t pad : 63;
CSR_STRUCT_END(vxsat)
CSR_STRUCT_START(vxrm)
uint64_t rm : 2;
uint64_t pad : 62;
CSR_STRUCT_END(vxrm)
CSR_STRUCT_START(vl)
CSR_STRUCT_END(vl)
CSR_STRUCT_START(vtype)
uint64_t vlmul : 3;
uint64_t vsew : 3;
uint64_t vediv : 2;
uint64_t pad : 55;
uint64_t vill : 1;
CSR_STRUCT_END(vtype)
rtlreg_t check_vsetvl(rtlreg_t vtype_req, rtlreg_t vl_req, bool max_req);
rtlreg_t get_mask(int reg, int idx, uint64_t vsew, uint64_t vlmul);
void set_mask(uint32_t reg, int idx, uint64_t mask, uint64_t vsew, uint64_t vlmul);
#endif // CONFIG_RVV_010
#define CSRS_DECL(name, addr) extern concat(name, _t)* const name;
MAP(CSRS, CSRS_DECL)
#ifdef CONFIG_RVV_010
MAP(VCSRS, CSRS_DECL)
#endif // CONFIG_RVV_010
word_t csrid_read(uint32_t csrid);
......
......@@ -25,4 +25,17 @@ static inline def_rtl(fsr, rtlreg_t *fdest, rtlreg_t *src, int width) {
fp_set_dirty();
}
#ifdef CONFIG_RVV_010
static inline def_rtl(lr, rtlreg_t* dest, int r, int width) {
rtl_mv(s, dest, &reg_l(r));
}
static inline def_rtl(sr, int r, const rtlreg_t *src1, int width) {
if (r != 0) { rtl_mv(s, &reg_l(r), src1); }
}
#endif // CONFIG_RVV_010
#endif
#ifdef CONFIG_RVV_010
#ifndef __RISCV64_VREG_H__
#define __RISCV64_VREG_H__
#include "common.h"
#define VLEN 256
#define VLENLG 8
#define MAXELEN 64
#define VENUM64 (VLEN/64)
#define VENUM32 (VLEN/32)
#define VENUM16 (VLEN/16)
#define VENUM8 (VLEN/8)
#define SLEN 256
static inline int check_reg_index1(int index) {
assert(index >= 0 && index < 32);
return index;
}
static inline int check_reg_index2(int index2, int elen) {
assert(index2 >= 0 && index2 < VLEN/elen);
return index2;
}
// #define vreg_len(index1, index2, elen) (cpu.vr[check_reg_index1(index1)]._64[check_reg_index2(index2, elen)])
#define vreg_ll(index) (cpu.vr[check_reg_index1(index)])
// #define vreg_l(index1, index2) vreg_len(index1, index2, 64)
// #define vreg_i(index1, index2) vreg_len(index1, index2, 32)
// #define vreg_s(index1, index2) vreg_len(index1, index2, 16)
// #define vreg_b(index1, index2) vreg_len(index1, index2, 8)
#define vreg_l(index1, index2) (cpu.vr[check_reg_index1(index1)]._64[check_reg_index2(index2, 64)])
#define vreg_i(index1, index2) (cpu.vr[check_reg_index1(index1)]._32[check_reg_index2(index2, 32)])
#define vreg_s(index1, index2) (cpu.vr[check_reg_index1(index1)]._16[check_reg_index2(index2, 16)])
#define vreg_b(index1, index2) (cpu.vr[check_reg_index1(index1)]._8[check_reg_index2(index2, 8)])
static inline const char * vreg_name(int index, int width) {
extern const char * vregsl[];
assert(index >= 0 && index < 32);
return vregsl[index];
}
void get_vreg(uint64_t reg, int idx, rtlreg_t *dst, uint64_t vsew, uint64_t vlmul, int is_signed, int needAlign);
void set_vreg(uint64_t reg, int idx, rtlreg_t src, uint64_t vsew, uint64_t vlmul, int needAlgin);
void longjmp_raise_intr(uint32_t foo);
#define SRC_VV 0
#define SRC_VI 1
#define SRC_VS 2
#define SRC_SI 3
#define UNSIGNED 0
#define SIGNED 1
#endif //__RISCV64_VREG_H__
#endif // CONFIG_RVV_010
\ No newline at end of file
......@@ -43,6 +43,18 @@ void isa_reg_display() {
mideleg->val, medeleg->val);
printf("mtval: " FMT_WORD " stval: " FMT_WORD " mtvec: " FMT_WORD " stvec: " FMT_WORD "\n",
mtval->val, stval->val, mtvec->val, stvec->val);
#ifdef CONFIG_RVV_010
//vector register
extern const char * vregsl[];
for(i = 0; i < 32; i ++) {
printf("%s: ", vregsl[i]);
printf("0x%016lx_%016lx_%016lx_%016lx ",
cpu.vr[i]._64[3], cpu.vr[i]._64[2], cpu.vr[i]._64[1], cpu.vr[i]._64[0]);
if(i%2) printf("\n");
}
printf("vtype: " FMT_WORD " vstart: " FMT_WORD " vxsat: " FMT_WORD "\n", vtype->val, vstart->val, vxsat->val);
printf("vxrm: " FMT_WORD " vl: " FMT_WORD "\n", vxrm->val, vl->val);
#endif // CONFIG_RVV_010
fflush(stdout);
}
......
......@@ -14,11 +14,17 @@ rtlreg_t csr_array[4096] = {};
#define CSRS_DEF(name, addr) \
concat(name, _t)* const name = (concat(name, _t) *)&csr_array[addr];
MAP(CSRS, CSRS_DEF)
#ifdef CONFIG_RVV_010
MAP(VCSRS, CSRS_DEF)
#endif // CONFIG_RVV_010
#define CSRS_EXIST(name, addr) csr_exist[addr] = 1;
static bool csr_exist[4096] = {};
void init_csr() {
MAP(CSRS, CSRS_EXIST)
#ifdef CONFIG_RVV_010
MAP(VCSRS, CSRS_EXIST)
#endif // CONFIG_RVV_010
};
rtlreg_t csr_perf;
......@@ -50,8 +56,11 @@ static inline word_t* csr_decode(uint32_t addr) {
}
return &csr_array[addr];
}
#ifdef CONFIG_RVV_010
#define SSTATUS_WMASK ((1 << 19) | (1 << 18) | (0x3 << 13) | (0x3 << 9) | (1 << 8) | (1 << 5) | (1 << 1))
#else
#define SSTATUS_WMASK ((1 << 19) | (1 << 18) | (0x3 << 13) | (1 << 8) | (1 << 5) | (1 << 1))
#endif // CONFIG_RVV_010
#define SSTATUS_RMASK (SSTATUS_WMASK | (0x3 << 15) | (1ull << 63) | (3ull << 32))
#define SIE_MASK (0x222 & mideleg->val)
#define SIP_MASK (0x222 & mideleg->val)
......@@ -86,6 +95,13 @@ static inline word_t csr_read(word_t *src) {
return *src;
}
#ifdef CONFIG_RVV_010
void vcsr_write(uint32_t addr, rtlreg_t *src) {
word_t *dest = csr_decode(addr);
*dest = *src;
}
#endif // CONFIG_RVV_010
static inline void csr_write(word_t *dest, word_t src) {
if (is_write(sstatus)) { mstatus->val = mask_bitset(mstatus->val, SSTATUS_WMASK, src); }
else if (is_write(sie)) { mie->val = mask_bitset(mie->val, SIE_MASK, src); }
......
......@@ -25,4 +25,11 @@ config MEM_RANDOM
help
This may help to find undefined behaviors.
config MEM_COMPRESS
depends on MODE_SYSTEM && !DIFFTEST
bool "Initialize the memory with a compressed gz file"
default n
help
Must have zlib installed.
endmenu #MEMORY
......@@ -17,6 +17,7 @@ static char *diff_so_file = NULL;
static char *img_file = NULL;
static int batch_mode = false;
static int difftest_port = 1234;
char *max_instr = NULL;
int is_batch_mode() { return batch_mode; }
......@@ -32,12 +33,68 @@ static inline void welcome() {
}
#ifndef CONFIG_MODE_USER
#ifdef CONFIG_MEM_COMPRESS
#include <zlib.h>
static long load_gz_img(const char *filename) {
gzFile compressed_mem = gzopen(filename, "rb");
Assert(compressed_mem, "Can not open '%s'", filename);
const uint32_t chunk_size = 16384;
uint8_t *temp_page = (uint8_t *)calloc(chunk_size, sizeof(long));
uint8_t *pmem_start = (uint8_t *)guest_to_host(RESET_VECTOR);
uint8_t *pmem_current;
// load file byte by byte to pmem
uint64_t curr_size = 0;
while (curr_size < CONFIG_MSIZE) {
uint32_t bytes_read = gzread(compressed_mem, temp_page, chunk_size);
if (bytes_read == 0) {
break;
}
for (uint32_t x = 0; x < bytes_read; x++) {
pmem_current = pmem_start + curr_size + x;
uint8_t read_data = *(temp_page + x);
if (read_data != 0 || *pmem_current != 0) {
*pmem_current = read_data;
}
}
curr_size += bytes_read;
}
// check again to ensure the bin has been fully loaded
uint32_t left_bytes = gzread(compressed_mem, temp_page, chunk_size);
Assert(left_bytes == 0, "File size is larger than buf_size!\n");
free(temp_page);
Assert(!gzclose(compressed_mem), "Error closing '%s'\n", filename);
return curr_size;
}
// Return whether a file is a gz file, determined by its name.
// If the filename ends with ".gz", we treat it as a gz file.
bool is_gz_file(const char *filename) {
if (filename == NULL || strlen(filename) < 3) {
return false;
}
return !strcmp(filename + (strlen(filename) - 3), ".gz");
}
#endif // CONFIG_MEM_COMPRESS
static inline long load_img() {
if (img_file == NULL) {
Log("No image is given. Use the default build-in image.");
return 4096; // built-in image size
}
#ifdef CONFIG_MEM_COMPRESS
if (is_gz_file(img_file)) {
Log("The image is %s", img_file);
return load_gz_img(img_file);
}
#endif
FILE *fp = fopen(img_file, "rb");
Assert(fp, "Can not open '%s'", img_file);
......@@ -53,11 +110,12 @@ static inline long load_img() {
fclose(fp);
return size;
}
#endif
#endif // CONFIG_MODE_USER
static inline int parse_args(int argc, char *argv[]) {
const struct option table[] = {
{"batch" , no_argument , NULL, 'b'},
{"max-instr", required_argument, NULL, 'I'},
{"log" , required_argument, NULL, 'l'},
{"diff" , required_argument, NULL, 'd'},
{"port" , required_argument, NULL, 'p'},
......@@ -65,9 +123,10 @@ static inline int parse_args(int argc, char *argv[]) {
{0 , 0 , NULL, 0 },
};
int o;
while ( (o = getopt_long(argc, argv, "-bhl:d:p:", table, NULL)) != -1) {
while ( (o = getopt_long(argc, argv, "-bI:hl:d:p:", table, NULL)) != -1) {
switch (o) {
case 'b': batch_mode = true; break;
case 'I': max_instr = optarg; break;
case 'p': sscanf(optarg, "%d", &difftest_port); break;
case 'l': log_file = optarg; break;
case 'd': diff_so_file = optarg; break;
......@@ -75,6 +134,7 @@ static inline int parse_args(int argc, char *argv[]) {
default:
printf("Usage: %s [OPTION...] IMAGE [args]\n\n", argv[0]);
printf("\t-b,--batch run with batch mode\n");
printf("\t-I,--max-instr max number of instructions executed\n");
printf("\t-l,--log=FILE output log to FILE\n");
printf("\t-d,--diff=REF_SO run DiffTest with reference REF_SO\n");
printf("\t-p,--port=PORT run DiffTest with port PORT\n");
......
......@@ -36,7 +36,7 @@ static char* rl_gets() {
}
static int cmd_c(char *args) {
cpu_exec(-1);
cpu_exec((args == NULL) ? -1 : atoi(args));
return 0;
}
......@@ -258,7 +258,8 @@ static int cmd_help(char *args) {
void ui_mainloop() {
if (is_batch_mode()) {
cmd_c(NULL);
extern char *max_instr;
cmd_c(max_instr);
return;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册