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

Merge branch 'rv64-cte' into 'rv64'

Rv64 cte

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