提交 7d909173 编写于 作者: Z Zihao Yu

Merge branch 'rv64-cte' into 'rv64'

Rv64 cte

See merge request projectn/nemu!4
......@@ -8,20 +8,21 @@
#define c_xor(a, b) ((a) ^ (b))
#define c_shl(a, b) ((a) << (b))
#define c_shr(a, b) ((a) >> (b))
#define c_shr64(a, b) ((uint32_t)(a) >> (b))
#define c_sar(a, b) ((int32_t)(a) >> (b))
#define c_sar64(a, b) ((int64_t)(a) >> (b))
#define c_sar(a, b) ((sword_t)(a) >> (b))
#define c_mul_lo(a, b) ((a) * (b))
#define c_mul_hi(a, b) (((uint64_t)(a) * (uint64_t)(b)) >> 32)
#define c_imul_lo(a, b) ((int32_t)(a) * (int32_t)(b))
#define c_imul_hi(a, b) (((int64_t)(int32_t)(a) * (int64_t)(int32_t)(b)) >> 32)
#define c_imul_lo(a, b) ((sword_t)(a) * (sword_t)(b))
#ifdef ISA64
# define c_mul_hi(a, b) (((__uint128_t)(a) * (__uint128_t)(b)) >> 64)
# define c_imul_hi(a, b) (((__int128_t)(sword_t)(a) * (__int128_t)(sword_t)(b)) >> 64)
#else
# define c_mul_hi(a, b) (((uint64_t)(a) * (uint64_t)(b)) >> 32)
# define c_imul_hi(a, b) (((int64_t)(sword_t)(a) * (int64_t)(sword_t)(b)) >> 32)
#endif
#define c_div_q(a, b) ((a) / (b))
#define c_div_q64(a, b) (((a) & 0xffffffff) / ((b) & 0xffffffff))
#define c_div_r(a, b) ((a) % (b))
#define c_div_r64(a, b) (((a) & 0xffffffff) % ((b) & 0xffffffff))
#define c_idiv_q(a, b) ((int32_t)(a) / (int32_t)(b))
#define c_idiv_q64(a, b) ((int32_t)((uint32_t)((a) & 0xffffffff)) / (int32_t)((uint32_t)((b) & 0xffffffff)))
#define c_idiv_r(a, b) ((int32_t)(a) % (int32_t)(b))
#define c_idiv_r64(a, b) ((int32_t)((uint32_t)((a) & 0xffffffff)) % (int32_t)((uint32_t)((b) & 0xffffffff)))
#define c_idiv_q(a, b) ((sword_t)(a) / (sword_t)(b))
#define c_idiv_r(a, b) ((sword_t)(a) % (sword_t)(b))
#endif
......@@ -14,21 +14,15 @@
#define rtl_xor concat(RTL_PREFIX, _rtl_xor )
#define rtl_shl concat(RTL_PREFIX, _rtl_shl )
#define rtl_shr concat(RTL_PREFIX, _rtl_shr )
#define rtl_shr64 concat(RTL_PREFIX, _rtl_shr64 )
#define rtl_sar concat(RTL_PREFIX, _rtl_sar )
#define rtl_sar64 concat(RTL_PREFIX, _rtl_sar64 )
#define rtl_mul_lo concat(RTL_PREFIX, _rtl_mul_lo )
#define rtl_mul_hi concat(RTL_PREFIX, _rtl_mul_hi )
#define rtl_imul_lo concat(RTL_PREFIX, _rtl_imul_lo )
#define rtl_imul_hi concat(RTL_PREFIX, _rtl_imul_hi )
#define rtl_div_q concat(RTL_PREFIX, _rtl_div_q )
#define rtl_div_q64 concat(RTL_PREFIX, _rtl_div_q64 )
#define rtl_div_r concat(RTL_PREFIX, _rtl_div_r )
#define rtl_div_r64 concat(RTL_PREFIX, _rtl_div_r64 )
#define rtl_idiv_q concat(RTL_PREFIX, _rtl_idiv_q )
#define rtl_idiv_q64 concat(RTL_PREFIX, _rtl_idiv_q64)
#define rtl_idiv_r concat(RTL_PREFIX, _rtl_idiv_r )
#define rtl_idiv_r64 concat(RTL_PREFIX, _rtl_idiv_r64)
#define rtl_div64_q concat(RTL_PREFIX, _rtl_div64_q )
#define rtl_div64_r concat(RTL_PREFIX, _rtl_div64_r )
#define rtl_idiv64_q concat(RTL_PREFIX, _rtl_idiv64_q)
......
......@@ -27,7 +27,7 @@ static inline void interpret_rtl_mv(rtlreg_t* dest, const rtlreg_t *src1) {
} \
/* Actually those of imm version are pseudo rtl instructions,
* but we define them here in the same macro */ \
static inline void concat(rtl_, name ## i) (rtlreg_t* dest, const rtlreg_t* src1, int imm) { \
static inline void concat(rtl_, name ## i) (rtlreg_t* dest, const rtlreg_t* src1, sword_t imm) { \
rtl_li(&ir, imm); \
rtl_ ## name (dest, src1, &ir); \
}
......@@ -49,15 +49,6 @@ make_rtl_arith_logic(div_r)
make_rtl_arith_logic(idiv_q)
make_rtl_arith_logic(idiv_r)
#ifdef ISA64
make_rtl_arith_logic(shr64)
make_rtl_arith_logic(sar64)
make_rtl_arith_logic(div_q64)
make_rtl_arith_logic(div_r64)
make_rtl_arith_logic(idiv_q64)
make_rtl_arith_logic(idiv_r64)
#endif
static inline void interpret_rtl_div64_q(rtlreg_t* dest,
const rtlreg_t* src1_hi, const rtlreg_t* src1_lo, const rtlreg_t* src2) {
uint64_t dividend = ((uint64_t)(*src1_hi) << 32) | (*src1_lo);
......@@ -142,7 +133,7 @@ void interpret_rtl_exit(int state, vaddr_t halt_pc, uint32_t halt_ret);
static inline void rtl_not(rtlreg_t *dest, const rtlreg_t* src1) {
// dest <- ~src1
// TODO();
rtl_xori(dest, src1, 0xffffffff);
rtl_xori(dest, src1, -1);
}
static inline void rtl_sext(rtlreg_t* dest, const rtlreg_t* src1, int width) {
......@@ -155,7 +146,7 @@ static inline void rtl_sext(rtlreg_t* dest, const rtlreg_t* src1, int width) {
} else {
assert(width == 1 || width == 2 || width == 4);
rtl_shli(dest, src1, (8 - width) * 8);
rtl_sar64i(dest, dest, (8 - width) * 8);
rtl_sari(dest, dest, (8 - width) * 8);
}
#else
if (width == 4) {
......
......@@ -2,14 +2,6 @@
#include "monitor/diff-test.h"
bool isa_difftest_checkregs(CPU_state *ref_r, vaddr_t pc) {
/*
int i;
for (i = 0; i < sizeof(cpu.gpr) / sizeof(cpu.gpr[0]); i ++) {
if (((uint64_t)cpu.gpr[i]._64) > ((uint64_t)0xffffffff)) {
printf("!!-0x%lx, 0x%lx\n", ref_r->gpr[i]._64, cpu.gpr[i]._64);
}
}*/
if (memcmp(&cpu, ref_r, DIFFTEST_REG_SIZE)) {
int i;
for (i = 0; i < sizeof(cpu.gpr) / sizeof(cpu.gpr[0]); i ++) {
......@@ -22,4 +14,6 @@ bool isa_difftest_checkregs(CPU_state *ref_r, vaddr_t pc) {
}
void isa_difftest_attach(void) {
ref_difftest_memcpy_from_dut(0, guest_to_host(0), PMEM_SIZE);
ref_difftest_setregs(&cpu);
}
......@@ -24,8 +24,8 @@ make_EHelper(sll) {
make_EHelper(srl) {
rtl_andi(&id_src2->val, &id_src2->val, 0x3f);
if (decinfo.isa.instr.funct7 == 32) {
// the LSB of funct7 may be "1" due to the shift amount can be >= 32
if ((decinfo.isa.instr.funct7 & ~0x1) == 32) {
// sra
rtl_sar(&s0, &id_src->val, &id_src2->val);
print_asm_template3(sra);
......@@ -34,7 +34,6 @@ make_EHelper(srl) {
rtl_shr(&s0, &id_src->val, &id_src2->val);
print_asm_template3(srl);
}
rtl_sr(id_dest->reg, &s0, 4);
}
......@@ -117,17 +116,19 @@ make_EHelper(sllw) {
}
make_EHelper(srlw) {
rtl_andi(&id_src2->val, &id_src2->val, 0x1f);
assert((decinfo.isa.instr.funct7 & 0x1) == 0);
if (decinfo.isa.instr.funct7 == 32) {
// sraw
rtl_sext(&id_src->val, &id_src->val, 4);
rtl_sar(&s0, &id_src->val, &id_src2->val);
rtl_sext(&s0, &s0, 4);
print_asm_template3(sraw);
}
else {
// srlw
rtl_andi(&id_src2->val, &id_src2->val, 0x1f);
rtl_shr64(&s0, &id_src->val, &id_src2->val);
rtl_andi(&id_src->val, &id_src->val, 0xffffffffu);
rtl_shr(&s0, &id_src->val, &id_src2->val);
rtl_sext(&s0, &s0, 4);
print_asm_template3(srlw);
}
......
......@@ -27,12 +27,12 @@ static make_EHelper(op_imm) {
idex(pc, &op_imm_table[decinfo.isa.instr.funct3]);
}
static OpcodeEntry op_imm_table64 [8] = {
EX(addw), EX(sllw), EMPTY, EMPTY, EMPTY, EX(sraw), EMPTY, EMPTY
static OpcodeEntry op_imm_table32 [8] = {
EX(addw), EX(sllw), EMPTY, EMPTY, EMPTY, EX(srlw), EMPTY, EMPTY
};
static make_EHelper(op_imm64) {
idex(pc, &op_imm_table64[decinfo.isa.instr.funct3]);
static make_EHelper(op_imm32) {
idex(pc, &op_imm_table32[decinfo.isa.instr.funct3]);
}
static OpcodeEntry op_table [8] = {
......@@ -56,23 +56,23 @@ static make_EHelper(op) {
}
}
static OpcodeEntry op_table64 [8] = {
static OpcodeEntry op_table32 [8] = {
EX(addw), EX(sllw), EMPTY, EMPTY, EMPTY, EX(srlw), EMPTY, EMPTY
};
static OpcodeEntry op2_table64 [8] = {
static OpcodeEntry op2_table32 [8] = {
EX(subw), EMPTY, EMPTY, EMPTY, EMPTY, EX(sraw), EMPTY, EMPTY
};
static OpcodeEntry muldiv_table64 [8] = {
static OpcodeEntry muldiv_table32 [8] = {
EX(mulw), EMPTY, EMPTY, EMPTY, EX(divw), EX(divuw), EX(remw), EX(remuw)
};
static make_EHelper(op64) {
static make_EHelper(op32) {
switch (decinfo.isa.instr.funct7) {
case 0: idex(pc, &op_table64[decinfo.isa.instr.funct3]); break;
case 1: idex(pc, &muldiv_table64[decinfo.isa.instr.funct3]); break;
case 32: idex(pc, &op2_table64[decinfo.isa.instr.funct3]); break;
case 0: idex(pc, &op_table32[decinfo.isa.instr.funct3]); break;
case 1: idex(pc, &muldiv_table32[decinfo.isa.instr.funct3]); break;
case 32: idex(pc, &op2_table32[decinfo.isa.instr.funct3]); break;
default: printf("not implemented\n"); assert(0);
}
}
......@@ -86,8 +86,8 @@ static make_EHelper(system) {
}
static OpcodeEntry opcode_table [32] = {
/* b00 */ IDEX(ld, load), EMPTY, EMPTY, EMPTY, IDEX(I, op_imm), IDEX(U, auipc), IDEX(I, op_imm64), EMPTY,
/* b01 */ IDEX(st, store), EMPTY, EMPTY, EMPTY, IDEX(R, op), IDEX(U, lui), IDEX(R, op64), EMPTY,
/* b00 */ IDEX(ld, load), EMPTY, EMPTY, EMPTY, IDEX(I, op_imm), IDEX(U, auipc), IDEX(I, op_imm32), EMPTY,
/* b01 */ IDEX(st, store), EMPTY, EMPTY, EMPTY, IDEX(R, op), IDEX(U, lui), IDEX(R, op32), EMPTY,
/* b10 */ EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
/* b11 */ IDEX(B, branch), IDEX(I, jalr), EX(nemu_trap), IDEX(J, jal), EX(system), EMPTY, EMPTY, EMPTY,
};
......
#include "cpu/exec.h"
make_EHelper(mul) {
#ifdef ISA64
rtl_mul_lo(&s0, &id_src->val, &id_src2->val);
#else
rtl_imul_lo(&s0, &id_src->val, &id_src2->val);
#endif
rtl_sr(id_dest->reg, &s0, 4);
print_asm_template3(mul);
......@@ -54,7 +50,7 @@ make_EHelper(remu) {
}
make_EHelper(mulw) {
rtl_imul_lo(&s0, &id_src->val, &id_src2->val);
rtl_mul_lo(&s0, &id_src->val, &id_src2->val);
rtl_sext(&s0, &s0, 4);
rtl_sr(id_dest->reg, &s0, 4);
......@@ -62,15 +58,19 @@ make_EHelper(mulw) {
}
make_EHelper(divw) {
rtl_idiv_q64(&s0, &id_src->val, &id_src2->val);
rtl_sext(&s0, &id_src->val, 4);
rtl_sext(&s1, &id_src2->val, 4);
rtl_idiv_q(&s0, &s0, &s1);
rtl_sext(&s0, &s0, 4);
rtl_sr(id_dest->reg, &s0, 4);
print_asm_template3(div);
print_asm_template3(divw);
}
make_EHelper(remw) {
rtl_idiv_r64(&s0, &id_src->val, &id_src2->val);
rtl_sext(&s0, &id_src->val, 4);
rtl_sext(&s1, &id_src2->val, 4);
rtl_idiv_r(&s0, &s0, &s1);
rtl_sext(&s0, &s0, 4);
rtl_sr(id_dest->reg, &s0, 4);
......@@ -78,7 +78,9 @@ make_EHelper(remw) {
}
make_EHelper(divuw) {
rtl_div_q64(&s0, &id_src->val, &id_src2->val);
rtl_andi(&s0, &id_src->val, 0xffffffffu);
rtl_andi(&s1, &id_src2->val, 0xffffffffu);
rtl_div_q(&s0, &s0, &s1);
rtl_sext(&s0, &s0, 4);
rtl_sr(id_dest->reg, &s0, 4);
......@@ -86,9 +88,11 @@ make_EHelper(divuw) {
}
make_EHelper(remuw) {
rtl_idiv_r64(&s0, &id_src->val, &id_src2->val);
rtl_andi(&s0, &id_src->val, 0xffffffffu);
rtl_andi(&s1, &id_src2->val, 0xffffffffu);
rtl_div_r(&s0, &s0, &s1);
rtl_sext(&s0, &s0, 4);
rtl_sr(id_dest->reg, &s0, 4);
print_asm_template3(remuw);
}
\ No newline at end of file
}
......@@ -5,10 +5,10 @@ static inline rtlreg_t* csr_decode(uint32_t csr) {
switch (csr) {
case 0x180: return &cpu.satp.val;
case 0x100: return &cpu.sstatus.val;
case 0x105: return &cpu.stvec;
case 0x141: return &cpu.sepc;
case 0x142: return &cpu.scause;
case 0x300: return &cpu.mstatus.val;
case 0x305: return &cpu.mtvec;
case 0x341: return &cpu.mepc;
case 0x342: return &cpu.mcause;
default: panic("unimplemented CSR 0x%x", csr);
}
return NULL;
......@@ -17,7 +17,7 @@ static inline rtlreg_t* csr_decode(uint32_t csr) {
make_EHelper(csrrw) {
rtlreg_t *csr = csr_decode(id_src2->val);
rtl_sr(id_dest->reg, csr, 4);
rtl_sr(id_dest->reg, csr, 8);
rtl_mv(csr, &id_src->val);
print_asm_template3("csrrw");
......@@ -26,7 +26,7 @@ make_EHelper(csrrw) {
make_EHelper(csrrs) {
rtlreg_t *csr = csr_decode(id_src2->val);
rtl_sr(id_dest->reg, csr, 4);
rtl_sr(id_dest->reg, csr, 8);
rtl_or(csr, csr, &id_src->val);
print_asm_template3("csrrs");
......@@ -38,15 +38,15 @@ make_EHelper(priv) {
uint32_t type = decinfo.isa.instr.csr;
switch (type) {
case 0:
raise_intr(9, cpu.pc);
raise_intr(11, cpu.pc);
print_asm("ecall");
break;
case 0x102:
cpu.sstatus.sie = cpu.sstatus.spie;
cpu.sstatus.spie = 1;
rtl_li(&s0, cpu.sepc);
case 0x302:
cpu.mstatus.mie = cpu.mstatus.mpie;
cpu.mstatus.mpie = 1;
rtl_li(&s0, cpu.mepc);
rtl_jr(&s0);
print_asm("sret");
print_asm("mret");
break;
default: panic("unimplemented priv instruction type = 0x%x", type);
}
......
......@@ -15,22 +15,25 @@ typedef struct {
} gpr[32];
vaddr_t pc;
vaddr_t stvec;
vaddr_t scause;
vaddr_t sepc;
vaddr_t mtvec;
vaddr_t mcause;
vaddr_t mepc;
union {
struct {
uint64_t uie : 1;
uint64_t sie : 1;
uint64_t pad0: 2;
uint64_t pad0: 1;
uint64_t mie : 1;
uint64_t upie: 1;
uint64_t spie: 1;
uint64_t pad1: 2;
uint64_t pad1: 1;
uint64_t mpie: 1;
uint64_t spp : 1;
uint64_t dontcare :31;
uint64_t pad2: 2;
uint64_t mpp : 2;
};
uint64_t val;
} sstatus;
} mstatus;
union {
struct {
uint64_t ppn :44;
......
......@@ -13,7 +13,7 @@ const long isa_default_img_size = sizeof(isa_default_img);
void init_isa(void) {
cpu.gpr[0]._64 = 0;
cpu.pc = PC_START;
cpu.sstatus.val = 0x000c0100;
cpu.mstatus.val = 0x000c0100;
register_pmem(0x80000000u);
}
#include "rtl/rtl.h"
void raise_intr(uint64_t NO, vaddr_t epc) {
void raise_intr(uint32_t NO, vaddr_t epc) {
/* TODO: Trigger an interrupt/exception with ``NO''.
* That is, use ``NO'' to index the IDT.
*/
cpu.scause = NO;
cpu.sepc = epc;
cpu.sstatus.spie = cpu.sstatus.sie;
cpu.sstatus.sie = 0;
rtl_li(&s0, cpu.stvec);
cpu.mcause = NO;
cpu.mepc = epc;
cpu.mstatus.mpie = cpu.mstatus.mie;
cpu.mstatus.mie = 0;
rtl_li(&s0, cpu.mtvec);
rtl_jr(&s0);
}
bool isa_query_intr(void) {
if (cpu.INTR && cpu.sstatus.sie) {
if (cpu.INTR && cpu.mstatus.mie) {
cpu.INTR = false;
raise_intr(0x80000005, cpu.pc);
return true;
......
......@@ -62,7 +62,7 @@ void cpu_exec(uint64_t n) {
WP *wp = scan_watchpoint();
if(wp != NULL) {
printf("\n\nHint watchpoint %d at address " FMT_WORD ", expr = %s\n", wp->NO, ori_pc, wp->expr);
printf("old value = %#08x\nnew value = %#08x\n", wp->old_val, wp->new_val);
printf("old value = " FMT_WORD "\nnew value = " FMT_WORD "\n", wp->old_val, wp->new_val);
wp->old_val = wp->new_val;
return;
}
......
......@@ -15,6 +15,7 @@ static bool is_detach = false;
// this is used to let ref skip instructions which
// can not produce consistent behavior with NEMU
void difftest_skip_ref() {
if (is_detach) return;
is_skip_ref = true;
}
......@@ -25,6 +26,7 @@ void difftest_skip_ref() {
// Let REF run `nr_ref` instructions first.
// We expect that DUT will catch up with REF within `nr_dut` instructions.
void difftest_skip_dut(int nr_ref, int nr_dut) {
if (is_detach) return;
skip_dut_nr_instr += nr_dut;
while (nr_ref -- > 0) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册