diff --git a/Makefile b/Makefile index 41651e7b62ede5ad47a57bad2768c01bae74906f..443bd82a737c0dc0bfbe57afb1e3e62d2f2e6150 100644 --- a/Makefile +++ b/Makefile @@ -58,6 +58,7 @@ CC = gcc LD = gcc INCLUDES = $(addprefix -I, $(INC_DIR)) CFLAGS += -O2 -MMD -Wall -Werror -ggdb3 $(INCLUDES) \ + -D__ENGINE_$(ENGINE)__ \ -D__ISA__=$(ISA) -D__ISA_$(ISA)__ -D_ISA_H_=\"isa/$(ISA).h\" # Files to be compiled diff --git a/include/isa/riscv64.h b/include/isa/riscv64.h index 3945203fd03151c53afa2dcc4bdb917d9e9a3752..d227e1ff3f118bfaf6aeddfbf79928af3b3ececa 100644 --- a/include/isa/riscv64.h +++ b/include/isa/riscv64.h @@ -4,7 +4,11 @@ #include // memory +#ifdef __ENGINE_rv64__ +#define riscv64_IMAGE_START 0x100000 +#else #define riscv64_IMAGE_START 0x0 +#endif #define riscv64_PMEM_BASE 0x80000000 // reg diff --git a/include/rtl/pseudo.h b/include/rtl/pseudo.h index eab7a6fa9f70818c15d097c04fbffaa7d810114b..9aff818c7624d3e6d4b33fd1fa1c6273a97382dc 100644 --- a/include/rtl/pseudo.h +++ b/include/rtl/pseudo.h @@ -41,6 +41,20 @@ static inline make_rtl(sext, rtlreg_t* dest, const rtlreg_t* src1, int width) { } } +static inline make_rtl(zext, rtlreg_t* dest, const rtlreg_t* src1, int width) { + // dest <- zeroext(src1[(width * 8 - 1) .. 0]) +// TODO(); + + const int word_size = sizeof(word_t); + if (width == word_size) { + rtl_mv(s, dest, src1); + } else { + assert(width == 1 || width == 2 || width == 4); + rtl_shli(s, dest, src1, (word_size - width) * 8); + rtl_shri(s, dest, dest, (word_size - width) * 8); + } +} + static inline make_rtl(msb, rtlreg_t* dest, const rtlreg_t* src1, int width) { // dest <- src1[width * 8 - 1] // TODO(); diff --git a/src/device/sdcard.c b/src/device/sdcard.c index 3c024187c8513a713527a7c7ed594ecf9aa34a7d..46c95b4491e09f1f24825bc98fc30dfb37a79f75 100644 --- a/src/device/sdcard.c +++ b/src/device/sdcard.c @@ -95,7 +95,8 @@ static void sdcard_io_handler(uint32_t offset, int len, bool is_write) { case SDDATA: // TODO if (!write_cmd && fp) { - fread(&base[SDDATA], 4, 1, fp); + __attribute__((unused)) int ret; + ret = fread(&base[SDDATA], 4, 1, fp); } addr += 4; break; diff --git a/src/engine/rv64/init.c b/src/engine/rv64/init.c index 0adea0d9dbdd43937903010a5d5107d87ede68fb..fb44451e78bcde9582af6003339674df737921d5 100644 --- a/src/engine/rv64/init.c +++ b/src/engine/rv64/init.c @@ -12,6 +12,7 @@ void (*backend_exec)(uint64_t n) = NULL; void backend_exec_code(uint64_t pc, int nr_instr); void guest_setregs(const CPU_state *cpu); +void spill_init(); static void init_rv64_interpreter() { char so_file[256]; @@ -75,6 +76,7 @@ static void init_rv64_reg() { backend_getregs(&r); r.gpr[mask32]._64 = 0x00000000fffffffful; r.gpr[mask16]._64 = 0x000000000000fffful; + if (spm_base != 0) r.gpr[spm_base]._64 = riscv64_PMEM_BASE; backend_setregs(&r); } @@ -85,4 +87,5 @@ void init_engine() { backend_exec_code(riscv64_PMEM_BASE, 100); guest_setregs(&cpu); init_rv64_reg(); + spill_init(); } diff --git a/src/engine/rv64/isa/mips32.c b/src/engine/rv64/isa/mips32.c index 85278d378ebadf8ea81058ec5464f92713e8cdd7..1be3ab18ced9fbc8521fa14e0e98709c58ee38c8 100644 --- a/src/engine/rv64/isa/mips32.c +++ b/src/engine/rv64/isa/mips32.c @@ -6,27 +6,31 @@ #include #include "../tran.h" -uint32_t reg_ptr2idx(DecodeExecState *s, const rtlreg_t* dest) { +uint32_t rtlreg2varidx(DecodeExecState *s, const rtlreg_t* dest) { rtlreg_t* gpr_start = (rtlreg_t *)cpu.gpr; rtlreg_t* gpr_end = (void *)gpr_start + sizeof(cpu.gpr); if (dest >= gpr_start && dest < gpr_end) { - int idx = dest - gpr_start; - switch (idx) { // idx - case 28: assert(0); break; // gp - case 1: case 26: case 27: break; // at, k0, k1 - case 25: assert(0); break; // t9 - default: return idx; + int rvidx = dest - gpr_start; + switch (rvidx) { + case tmp0: return 1 | SPMIDX_MASK; // fixed to tmp0 + case spm_base: return 2 | SPMIDX_MASK; // used to store sratchpad addr + case tmp_reg1: return 3 | SPMIDX_MASK; // tmp_reg 1 + case tmp_reg2: return 4 | SPMIDX_MASK; // tmp_reg 2 + case mask32: return 5 | SPMIDX_MASK; // fixed to mask32 + default: return rvidx; } } + if (dest == rz) return 0; + + // other temps + if (dest == &cpu.lo) return 6 | SPMIDX_MASK; + if (dest == &cpu.hi) return 7 | SPMIDX_MASK; + if (dest == s0) return 8 | SPMIDX_MASK; + if (dest == s1) return 9 | SPMIDX_MASK; -#define CASE(ptr, idx) if (dest == ptr) return idx; - CASE(rz, 0) - CASE(&cpu.lo, 25) - CASE(&cpu.hi, 27) - CASE(s0, 26) - //CASE(s1, 27) panic("bad ptr = %p", dest); + return 0; } void guest_getregs(CPU_state *mips32) { @@ -35,10 +39,11 @@ void guest_getregs(CPU_state *mips32) { int i; for (i = 0; i < 32; i ++) { switch (i) { - case 28: case 1: case 26: case 27: case 25: continue; + case tmp0: case mask32: case spm_base: case tmp_reg1: case tmp_reg2: continue; } mips32->gpr[i]._32 = r.gpr[i]._64; } + // FIXME: these are wrong mips32->lo = r.gpr[25]._64; mips32->hi = r.gpr[27]._64; } @@ -49,10 +54,11 @@ void guest_setregs(const CPU_state *mips32) { int i; for (i = 0; i < 32; i ++) { switch (i) { - case 28: case 1: case 26: case 27: case 25: continue; + case tmp0: case mask32: case spm_base: case tmp_reg1: case tmp_reg2: continue; } r.gpr[i]._64 = mips32->gpr[i]._32; } + // FIXME: these are wrong r.gpr[25]._64 = mips32->lo; r.gpr[27]._64 = mips32->hi; backend_setregs(&r); diff --git a/src/engine/rv64/isa/riscv32.c b/src/engine/rv64/isa/riscv32.c index 584b351c41bc2533c191dd00a1c659fec21a548e..56ffd2a5fd9d2b9a35dd83cd7baad4832c960330 100644 --- a/src/engine/rv64/isa/riscv32.c +++ b/src/engine/rv64/isa/riscv32.c @@ -6,22 +6,29 @@ #include #include "../tran.h" -uint32_t reg_ptr2idx(DecodeExecState *s, const rtlreg_t* dest) { +uint32_t rtlreg2varidx(DecodeExecState *s, const rtlreg_t* dest) { rtlreg_t* gpr_start = (rtlreg_t *)cpu.gpr; rtlreg_t* gpr_end = (void *)gpr_start + sizeof(cpu.gpr); if (dest >= gpr_start && dest < gpr_end) { - int idx = dest - gpr_start; - switch (idx) { // idx - case 3: case 4: case 31: assert(0); break; // gp, tp, t6 - default: return idx; + int rvidx = dest - gpr_start; + switch (rvidx) { + case tmp0: return 1 | SPMIDX_MASK; // fixed to tmp0 + case spm_base: return 2 | SPMIDX_MASK; // used to store sratchpad addr + case tmp_reg1: return 3 | SPMIDX_MASK; // tmp_reg 1 + case tmp_reg2: return 4 | SPMIDX_MASK; // tmp_reg 2 + case mask32: return 5 | SPMIDX_MASK; // fixed to mask32 + default: return rvidx; } } + if (dest == rz) return 0; + + // other temps + if (dest == s0) return 6 | SPMIDX_MASK; + if (dest == s1) return 7 | SPMIDX_MASK; -#define CASE(ptr, idx) if (dest == ptr) return idx; - CASE(rz, 0) - CASE(s0, 31) panic("bad ptr = %p", dest); + return 0; } void guest_getregs(CPU_state *riscv32) { @@ -30,7 +37,7 @@ void guest_getregs(CPU_state *riscv32) { int i; for (i = 0; i < 32; i ++) { switch (i) { - case 3: case 4: case 31: continue; + case tmp0: case mask32: case spm_base: case tmp_reg1: case tmp_reg2: continue; } riscv32->gpr[i]._32 = r.gpr[i]._64; } @@ -42,7 +49,7 @@ void guest_setregs(const CPU_state *riscv32) { int i; for (i = 0; i < 32; i ++) { switch (i) { - case 3: case 4: case 31: continue; + case tmp0: case mask32: case spm_base: case tmp_reg1: case tmp_reg2: continue; } r.gpr[i]._64 = riscv32->gpr[i]._32; } diff --git a/src/engine/rv64/isa/riscv64.c b/src/engine/rv64/isa/riscv64.c new file mode 100644 index 0000000000000000000000000000000000000000..cc97836007a16d99a377d21f7fbaba0478955817 --- /dev/null +++ b/src/engine/rv64/isa/riscv64.c @@ -0,0 +1,58 @@ +#ifdef __ISA_riscv64__ + +#include +#include +#include +#include +#include "../tran.h" + +uint32_t rtlreg2varidx(DecodeExecState *s, const rtlreg_t* dest) { + rtlreg_t* gpr_start = (rtlreg_t *)cpu.gpr; + rtlreg_t* gpr_end = (void *)gpr_start + sizeof(cpu.gpr); + + if (dest >= gpr_start && dest < gpr_end) { + int rvidx = dest - gpr_start; + switch (rvidx) { + case tmp0: return 1 | SPMIDX_MASK; // fixed to tmp0 + case spm_base: return 2 | SPMIDX_MASK; // used to store sratchpad addr + case tmp_reg1: return 3 | SPMIDX_MASK; // tmp_reg 1 + case tmp_reg2: return 4 | SPMIDX_MASK; // tmp_reg 2 + default: return rvidx; + } + } + if (dest == rz) return 0; + + // other temps + if (dest == s0) return 6 | SPMIDX_MASK; + if (dest == s1) return 7 | SPMIDX_MASK; + + panic("bad ptr = %p", dest); + return 0; +} + +void guest_getregs(CPU_state *riscv64) { + riscv64_CPU_state r; + backend_getregs(&r); + int i; + for (i = 0; i < 32; i ++) { + switch (i) { + case tmp0: case spm_base: case tmp_reg1: case tmp_reg2: continue; + } + riscv64->gpr[i]._64 = r.gpr[i]._64; + } +} + +void guest_setregs(const CPU_state *riscv64) { + riscv64_CPU_state r; + backend_getregs(&r); + int i; + for (i = 0; i < 32; i ++) { + switch (i) { + case tmp0: case spm_base: case tmp_reg1: case tmp_reg2: continue; + } + r.gpr[i]._64 = riscv64->gpr[i]._64; + } + backend_setregs(&r); +} + +#endif diff --git a/src/engine/rv64/isa/x86.c b/src/engine/rv64/isa/x86.c index c40426183f4573cfdd2840002c869bbb036abd9f..1b6955f973b7aee7b0f67a25f15d41c2a7fd2f4d 100644 --- a/src/engine/rv64/isa/x86.c +++ b/src/engine/rv64/isa/x86.c @@ -6,7 +6,7 @@ #include #include "../tran.h" -uint32_t reg_ptr2idx(DecodeExecState *s, const rtlreg_t* dest) { +uint32_t rtlreg2varidx(DecodeExecState *s, const rtlreg_t* dest) { rtlreg_t* gpr_start = (rtlreg_t *)cpu.gpr; rtlreg_t* gpr_end = (void *)gpr_start + sizeof(cpu.gpr); diff --git a/src/engine/rv64/rv64-backend/rtl-basic.c b/src/engine/rv64/rv64-backend/rtl-basic.c index 22bf5e4a5de70893b55f87a2c737043943beae32..7020aa64272114d97963f04bc7638a2d6a0f3553 100644 --- a/src/engine/rv64/rv64-backend/rtl-basic.c +++ b/src/engine/rv64/rv64-backend/rtl-basic.c @@ -1,17 +1,23 @@ #include #include "rv_ins_def.h" #include "../tran.h" +#include "../spill.h" void rv64_relop(uint32_t relop, uint32_t idx_dest, uint32_t idx_src1, uint32_t idx_src2); -uint32_t reg_ptr2idx(DecodeExecState *s, const rtlreg_t* dest); +uint32_t dest2rvidx(DecodeExecState *s, const rtlreg_t* dest); +uint32_t src2rvidx(DecodeExecState *s, const rtlreg_t* src); static inline void rv64_zextw(uint32_t rd, uint32_t rs) { +#ifndef ISA64 // mask32 is set during initialization rv64_and(rd, rs, mask32); +#endif } static inline void rv64_sextw(uint32_t rd, uint32_t rs) { +#ifndef ISA64 rv64_addw(rd, rs, x0); +#endif } // return false if `imm` can be represented within 12 bits @@ -22,79 +28,66 @@ static inline bool load_imm_big(uint32_t r, const sword_t imm) { if (lui_imm == 0) return false; else { rv64_lui(r, lui_imm); - if (rv_imm.imm_11_0 != 0) rv64_addiw(r, r, rv_imm.imm_11_0); + if (rv_imm.imm_11_0 != 0) rv64_addi(r, r, rv_imm.imm_11_0); return true; } } static inline void load_imm(uint32_t r, const sword_t imm) { - if (imm == 0) { - rv64_addi(r, x0, 0); - return; - } - - RV_IMM rv_imm = { .val = imm }; - uint32_t lui_imm = (rv_imm.imm_31_12 + (rv_imm.imm_11_0 >> 11)) & 0xfffffu; - - uint32_t hi = x0; - if (lui_imm != 0) { - rv64_lui(r, lui_imm); - hi = r; - } - if (rv_imm.imm_11_0 != 0) rv64_addiw(r, hi, rv_imm.imm_11_0); + if (!load_imm_big(r, imm)) rv64_addi(r, x0, imm & 0xfff); } static inline void load_imm_no_opt(uint32_t r, const sword_t imm) { RV_IMM rv_imm = { .val = imm }; uint32_t lui_imm = (rv_imm.imm_31_12 + (rv_imm.imm_11_0 >> 11)) & 0xfffffu; rv64_lui(r, lui_imm); - rv64_addiw(r, r, rv_imm.imm_11_0); + rv64_addi(r, r, rv_imm.imm_11_0); } /* RTL basic instructions */ #define make_rtl_compute_reg(rtl_name, rv64_name) \ make_rtl(rtl_name, rtlreg_t* dest, const rtlreg_t* src1, const rtlreg_t* src2) { \ - concat(rv64_, rv64_name) (reg_ptr2idx(s, dest), reg_ptr2idx(s, src1), reg_ptr2idx(s, src2)); \ + uint32_t ret = rtlreg2rvidx_pair(s, src1, true, src2, true); \ + uint32_t src1_rvidx = ret >> 16; \ + uint32_t src2_rvidx = ret & 0xffff; \ + uint32_t dest_rvidx = dest2rvidx(s, dest); \ + concat(rv64_, rv64_name) (dest_rvidx, src1_rvidx, src2_rvidx); \ } #define make_rtl_compute_imm(rtl_name, rv64_name) \ make_rtl(rtl_name, rtlreg_t* dest, const rtlreg_t* src1, const sword_t imm) { \ - concat(rv64_, rv64_name) (reg_ptr2idx(s, dest), reg_ptr2idx(s, src1), imm); \ + uint32_t ret = rtlreg2rvidx_pair(s, dest, false, src1, true); \ + uint32_t dest_rvidx = ret >> 16; \ + uint32_t src1_rvidx = ret & 0xffff; \ + concat(rv64_, rv64_name) (dest_rvidx, src1_rvidx, imm); \ + spill_set_dirty_rvidx(dest_rvidx); \ + } + +#define make_rtl_compute_imm_opt(rtl_name, rv64_name, rv64_imm_name) \ + make_rtl(rtl_name, rtlreg_t* dest, const rtlreg_t* src1, const sword_t imm) { \ + uint32_t ret = rtlreg2rvidx_pair(s, dest, false, src1, true); \ + uint32_t dest_rvidx = ret >> 16; \ + uint32_t src1_rvidx = ret & 0xffff; \ + if (src1 == rz) load_imm(dest_rvidx, imm); \ + else if (load_imm_big(tmp0, imm)) concat(rv64_, rv64_name) (dest_rvidx, src1_rvidx, tmp0); \ + else concat(rv64_, rv64_imm_name) (dest_rvidx, src1_rvidx, imm); \ + spill_set_dirty_rvidx(dest_rvidx); \ } make_rtl_compute_reg(and, and) make_rtl_compute_reg(or, or) make_rtl_compute_reg(xor, xor) -make_rtl(addi, rtlreg_t* dest, const rtlreg_t* src1, const sword_t imm) { - if (src1 == rz) load_imm(reg_ptr2idx(s, dest), imm); - else if (load_imm_big(tmp0, imm)) rv64_addw(reg_ptr2idx(s, dest), reg_ptr2idx(s, src1), tmp0); - else rv64_addiw(reg_ptr2idx(s, dest), reg_ptr2idx(s, src1), imm); -} +make_rtl_compute_imm_opt(addi, add, addi) +make_rtl_compute_imm_opt(andi, and, andi) +make_rtl_compute_imm_opt(xori, xor, xori) +make_rtl_compute_imm_opt(ori, or, ori) make_rtl(subi, rtlreg_t* dest, const rtlreg_t* src1, const sword_t imm) { rtl_addi(s, dest, src1, -imm); } -make_rtl(andi, rtlreg_t* dest, const rtlreg_t* src1, const sword_t imm) { - if (src1 == rz) load_imm(reg_ptr2idx(s, dest), 0); - else if (load_imm_big(tmp0, imm)) rv64_and(reg_ptr2idx(s, dest), reg_ptr2idx(s, src1), tmp0); - else rv64_andi(reg_ptr2idx(s, dest), reg_ptr2idx(s, src1), imm); -} - -make_rtl(xori, rtlreg_t* dest, const rtlreg_t* src1, const sword_t imm) { - if (src1 == rz) load_imm(reg_ptr2idx(s, dest), imm); - else if (load_imm_big(tmp0, imm)) rv64_xor(reg_ptr2idx(s, dest), reg_ptr2idx(s, src1), tmp0); - else rv64_xori(reg_ptr2idx(s, dest), reg_ptr2idx(s, src1), imm); -} - -make_rtl(ori, rtlreg_t* dest, const rtlreg_t* src1, const sword_t imm) { - if (src1 == rz) load_imm(reg_ptr2idx(s, dest), imm); - else if (load_imm_big(tmp0, imm)) rv64_or(reg_ptr2idx(s, dest), reg_ptr2idx(s, src1), tmp0); - else rv64_ori(reg_ptr2idx(s, dest), reg_ptr2idx(s, src1), imm); -} - #ifdef ISA64 make_rtl_compute_reg(add, add) make_rtl_compute_reg(sub, sub) @@ -116,27 +109,42 @@ make_rtl_compute_imm(sari, sraiw) #endif make_rtl(setrelop, uint32_t relop, rtlreg_t *dest, const rtlreg_t *src1, const rtlreg_t *src2) { - rv64_relop(relop, reg_ptr2idx(s, dest), reg_ptr2idx(s, src1), reg_ptr2idx(s, src2)); + uint32_t ret = rtlreg2rvidx_pair(s, src1, true, src2, true); + uint32_t src1_rvidx = ret >> 16; + uint32_t src2_rvidx = ret & 0xffff; + uint32_t dest_rvidx = dest2rvidx(s, dest); + rv64_relop(relop, dest_rvidx, src1_rvidx, src2_rvidx); } make_rtl(setrelopi, uint32_t relop, rtlreg_t *dest, const rtlreg_t *src1, const sword_t imm) { int big_imm = load_imm_big(tmp0, imm); - uint32_t idx_dest = reg_ptr2idx(s, dest); - uint32_t idx_src1 = reg_ptr2idx(s, src1); + uint32_t ret = rtlreg2rvidx_pair(s, dest, false, src1, true); + uint32_t dest_rvidx = ret >> 16; + uint32_t src1_rvidx = ret & 0xffff; if (!big_imm && (relop == RELOP_LT || relop == RELOP_LTU)) { switch (relop) { - case RELOP_LT: rv64_slti(idx_dest, idx_src1, imm); return; - case RELOP_LTU: rv64_sltiu(idx_dest, idx_src1, imm); return; + case RELOP_LT: rv64_slti(dest_rvidx, src1_rvidx, imm); goto finish; + case RELOP_LTU: rv64_sltiu(dest_rvidx, src1_rvidx, imm); goto finish; // fall through for default cases } } - if (!big_imm) rv64_addiw(tmp0, x0, imm); - rv64_relop(relop, idx_dest, idx_src1, tmp0); + if (!big_imm) rv64_addi(tmp0, x0, imm); + rv64_relop(relop, dest_rvidx, src1_rvidx, tmp0); +finish: + spill_set_dirty_rvidx(dest_rvidx); } -//make_rtl_arith_logic(mul_hi) -//make_rtl_arith_logic(imul_hi) +#ifdef ISA64 +make_rtl_compute_reg(mul_lo, mul) +make_rtl_compute_reg(mul_hi, mulhu) +make_rtl_compute_reg(imul_lo, mul) +make_rtl_compute_reg(imul_hi, mulh) +make_rtl_compute_reg(div_q, divu) +make_rtl_compute_reg(div_r, remu) +make_rtl_compute_reg(idiv_q, div) +make_rtl_compute_reg(idiv_r, rem) +#else make_rtl_compute_reg(mul_lo, mulw) make_rtl_compute_reg(imul_lo, mulw) make_rtl_compute_reg(div_q, divuw) @@ -144,146 +152,129 @@ make_rtl_compute_reg(div_r, remuw) make_rtl_compute_reg(idiv_q, divw) make_rtl_compute_reg(idiv_r, remw) -#ifdef ISA64 -# define rv64_mul_hi(c, a, b) TODO() -# define rv64_imul_hi(c, a, b) TODO() -#else make_rtl(mul_hi, rtlreg_t* dest, const rtlreg_t* src1, const rtlreg_t* src2) { - uint32_t idx_dest = reg_ptr2idx(s, dest); - uint32_t idx_src1 = reg_ptr2idx(s, src1); - uint32_t idx_src2 = reg_ptr2idx(s, src2); - rv64_zextw(idx_src1, idx_src1); - rv64_zextw(idx_src2, idx_src2); - rv64_mul(idx_dest, idx_src1, idx_src2); - rv64_srai(idx_dest, idx_dest, 32); + uint32_t ret = rtlreg2rvidx_pair(s, src1, true, src2, true); + uint32_t src1_rvidx = ret >> 16; + uint32_t src2_rvidx = ret & 0xffff; + rv64_zextw(src1_rvidx, src1_rvidx); + rv64_zextw(src2_rvidx, src2_rvidx); + uint32_t dest_rvidx = dest2rvidx(s, dest); + rv64_mul(dest_rvidx, src1_rvidx, src2_rvidx); + rv64_srai(dest_rvidx, dest_rvidx, 32); } make_rtl(imul_hi, rtlreg_t* dest, const rtlreg_t* src1, const rtlreg_t* src2) { - uint32_t idx_dest = reg_ptr2idx(s, dest); - uint32_t idx_src1 = reg_ptr2idx(s, src1); - uint32_t idx_src2 = reg_ptr2idx(s, src2); - rv64_sextw(idx_src1, idx_src1); - rv64_sextw(idx_src2, idx_src2); - rv64_mul(idx_dest, idx_src1, idx_src2); - rv64_srai(idx_dest, idx_dest, 32); + uint32_t ret = rtlreg2rvidx_pair(s, src1, true, src2, true); + uint32_t src1_rvidx = ret >> 16; + uint32_t src2_rvidx = ret & 0xffff; + rv64_sextw(src1_rvidx, src1_rvidx); + rv64_sextw(src2_rvidx, src2_rvidx); + uint32_t dest_rvidx = dest2rvidx(s, dest); + rv64_mul(dest_rvidx, src1_rvidx, src2_rvidx); + rv64_srai(dest_rvidx, dest_rvidx, 32); } #endif -make_rtl(div64_q, rtlreg_t* dest, - const rtlreg_t* src1_hi, const rtlreg_t* src1_lo, const rtlreg_t* src2) { - uint32_t idx_dest = reg_ptr2idx(s, dest); - uint32_t idx_src1_hi = reg_ptr2idx(s, src1_hi); - uint32_t idx_src1_lo = reg_ptr2idx(s, src1_lo); - uint32_t idx_src2 = reg_ptr2idx(s, src2); - - rv64_slli(tmp0, idx_src1_hi, 32); - rv64_zextw(idx_src1_lo, idx_src1_lo); - rv64_or(tmp0, tmp0, idx_src1_lo); - rv64_zextw(idx_src2, idx_src2); - rv64_divu(idx_dest, tmp0, idx_src2); -} - -make_rtl(div64_r, rtlreg_t* dest, - const rtlreg_t* src1_hi, const rtlreg_t* src1_lo, const rtlreg_t* src2) { - uint32_t idx_dest = reg_ptr2idx(s, dest); - uint32_t idx_src1_hi = reg_ptr2idx(s, src1_hi); - uint32_t idx_src1_lo = reg_ptr2idx(s, src1_lo); - uint32_t idx_src2 = reg_ptr2idx(s, src2); - - rv64_slli(tmp0, idx_src1_hi, 32); - rv64_zextw(idx_src1_lo, idx_src1_lo); - rv64_or(tmp0, tmp0, idx_src1_lo); - rv64_zextw(idx_src2, idx_src2); - rv64_remu(idx_dest, tmp0, idx_src2); +#ifdef __ISA_x86__ +#define make_x86_div64(rtl_name, ext_type, rv64_name) \ +make_rtl(rtl_name, rtlreg_t* dest, \ + const rtlreg_t* src1_hi, const rtlreg_t* src1_lo, const rtlreg_t* src2) { \ + uint32_t idx_dest = dest2rvidx(s, dest); \ + uint32_t idx_src1_hi = src2rvidx(s, src1_hi); \ + uint32_t idx_src1_lo = src2rvidx(s, src1_lo); \ + uint32_t idx_src2 = src2rvidx(s, src2); \ + rv64_slli(tmp0, idx_src1_hi, 32); \ + rv64_zextw(idx_src1_lo, idx_src1_lo); \ + rv64_or(tmp0, tmp0, idx_src1_lo); \ + ext_type(idx_src2, idx_src2); \ + concat(rv64_, rv64_name) (idx_dest, tmp0, idx_src2); \ } - -make_rtl(idiv64_q, rtlreg_t* dest, - const rtlreg_t* src1_hi, const rtlreg_t* src1_lo, const rtlreg_t* src2) { - uint32_t idx_dest = reg_ptr2idx(s, dest); - uint32_t idx_src1_hi = reg_ptr2idx(s, src1_hi); - uint32_t idx_src1_lo = reg_ptr2idx(s, src1_lo); - uint32_t idx_src2 = reg_ptr2idx(s, src2); - - rv64_slli(tmp0, idx_src1_hi, 32); - rv64_zextw(idx_src1_lo, idx_src1_lo); - rv64_or(tmp0, tmp0, idx_src1_lo); - rv64_sextw(idx_src2, idx_src2); - rv64_div(idx_dest, tmp0, idx_src2); +#else +#define make_x86_div64(rtl_name, ext_type, rv64_name) \ +make_rtl(rtl_name, rtlreg_t* dest, \ + const rtlreg_t* src1_hi, const rtlreg_t* src1_lo, const rtlreg_t* src2) { \ + panic("only support in x86"); \ } +#endif -make_rtl(idiv64_r, rtlreg_t* dest, - const rtlreg_t* src1_hi, const rtlreg_t* src1_lo, const rtlreg_t* src2) { - uint32_t idx_dest = reg_ptr2idx(s, dest); - uint32_t idx_src1_hi = reg_ptr2idx(s, src1_hi); - uint32_t idx_src1_lo = reg_ptr2idx(s, src1_lo); - uint32_t idx_src2 = reg_ptr2idx(s, src2); - - rv64_slli(tmp0, idx_src1_hi, 32); - rv64_zextw(idx_src1_lo, idx_src1_lo); - rv64_or(tmp0, tmp0, idx_src1_lo); - rv64_sextw(idx_src2, idx_src2); - rv64_rem(idx_dest, tmp0, idx_src2); -} +make_x86_div64(div64_q, rv64_zextw, divu) +make_x86_div64(div64_r, rv64_zextw, remu) +make_x86_div64(idiv64_q, rv64_sextw, div) +make_x86_div64(idiv64_r, rv64_sextw, rem) make_rtl(lm, rtlreg_t *dest, const rtlreg_t* addr, const sword_t imm, int len) { - uint32_t idx_dest = reg_ptr2idx(s, dest); - uint32_t idx_addr = reg_ptr2idx(s, addr); + uint32_t ret = rtlreg2rvidx_pair(s, dest, false, addr, true); + uint32_t dest_rvidx = ret >> 16; + uint32_t addr_rvidx = ret & 0xffff; + uint32_t addr_rvidx_final = dest_rvidx; RV_IMM rv_imm = { .val = imm }; uint32_t lui_imm = (rv_imm.imm_31_12 + (rv_imm.imm_11_0 >> 11)) & 0xfffffu; - if (addr == rz) rv64_lui(tmp0, lui_imm); - else if (lui_imm == 0) rv64_zextw(tmp0, idx_addr); + if (addr == rz) rv64_lui(dest_rvidx, lui_imm); + else if (lui_imm == 0) { +#ifdef ISA64 + addr_rvidx_final = addr_rvidx; +#else + rv64_zextw(dest_rvidx, addr_rvidx); +#endif + } else { rv64_lui(tmp0, lui_imm); - rv64_add(tmp0, tmp0, idx_addr); - rv64_zextw(tmp0, tmp0); + rv64_add(dest_rvidx, tmp0, addr_rvidx); + rv64_zextw(dest_rvidx, dest_rvidx); } switch (len) { - case 1: rv64_lbu(idx_dest, tmp0, imm & 0xfff); break; - case 2: rv64_lhu(idx_dest, tmp0, imm & 0xfff); break; + case 1: rv64_lbu(dest_rvidx, addr_rvidx_final, imm & 0xfff); break; + case 2: rv64_lhu(dest_rvidx, addr_rvidx_final, imm & 0xfff); break; #ifdef ISA64 - case 4: rv64_lwu(idx_dest, tmp0, imm & 0xfff); break; + case 4: rv64_lwu(dest_rvidx, addr_rvidx_final, imm & 0xfff); break; #else - case 4: rv64_lw (idx_dest, tmp0, imm & 0xfff); break; + case 4: rv64_lw (dest_rvidx, addr_rvidx_final, imm & 0xfff); break; #endif - case 8: rv64_ld (idx_dest, tmp0, imm & 0xfff); break; + case 8: rv64_ld (dest_rvidx, addr_rvidx_final, imm & 0xfff); break; default: assert(0); } + spill_set_dirty_rvidx(dest_rvidx); } make_rtl(sm, const rtlreg_t* addr, const sword_t imm, const rtlreg_t* src1, int len) { - uint32_t idx_addr = reg_ptr2idx(s, addr); - uint32_t idx_src1 = reg_ptr2idx(s, src1); + uint32_t ret = rtlreg2rvidx_pair(s, addr, true, src1, true); + uint32_t addr_rvidx = ret >> 16; + uint32_t src1_rvidx = ret & 0xffff; + uint32_t addr_rvidx_final = tmp0; RV_IMM rv_imm = { .val = imm }; uint32_t lui_imm = (rv_imm.imm_31_12 + (rv_imm.imm_11_0 >> 11)) & 0xfffffu; if (addr == rz) rv64_lui(tmp0, lui_imm); - else if (lui_imm == 0) rv64_zextw(tmp0, idx_addr); + else if (lui_imm == 0) { +#ifdef ISA64 + addr_rvidx_final = addr_rvidx; +#else + rv64_zextw(tmp0, addr_rvidx); +#endif + } else { rv64_lui(tmp0, lui_imm); - rv64_add(tmp0, tmp0, idx_addr); + rv64_add(tmp0, tmp0, addr_rvidx); rv64_zextw(tmp0, tmp0); } switch (len) { - case 1: rv64_sb(idx_src1, tmp0, imm & 0xfff); break; - case 2: rv64_sh(idx_src1, tmp0, imm & 0xfff); break; - case 4: rv64_sw(idx_src1, tmp0, imm & 0xfff); break; - case 8: rv64_sd(idx_src1, tmp0, imm & 0xfff); break; + case 1: rv64_sb(src1_rvidx, addr_rvidx_final, imm & 0xfff); break; + case 2: rv64_sh(src1_rvidx, addr_rvidx_final, imm & 0xfff); break; + case 4: rv64_sw(src1_rvidx, addr_rvidx_final, imm & 0xfff); break; + case 8: rv64_sd(src1_rvidx, addr_rvidx_final, imm & 0xfff); break; default: assert(0); } } +#ifdef __ISA_x86__ make_rtl(host_lm, rtlreg_t* dest, const void *addr, int len) { -#ifndef __ISA_x86__ - panic("should not reach here"); -#endif - - uint32_t idx_dest = reg_ptr2idx(s, dest); + uint32_t idx_dest = dest2rvidx(s, dest); // we assume that `addr` is only from cpu.gpr in x86 uintptr_t addr_align = (uintptr_t)addr & ~(sizeof(rtlreg_t) - 1); - uint32_t idx_r = reg_ptr2idx(s, (void *)addr_align); + uint32_t idx_r = src2rvidx(s, (void *)addr_align); switch (len) { case 1: ; int is_high = (uintptr_t)addr & 1; @@ -302,15 +293,11 @@ make_rtl(host_lm, rtlreg_t* dest, const void *addr, int len) { } make_rtl(host_sm, void *addr, const rtlreg_t *src1, int len) { -#ifndef __ISA_x86__ - panic("should not reach here"); -#endif - - uint32_t idx_src1 = reg_ptr2idx(s, src1); + uint32_t idx_src1 = dest2rvidx(s, src1); // we assume that `addr` is only from cpu.gpr in x86 uintptr_t addr_align = (uintptr_t)addr & ~(sizeof(rtlreg_t) - 1); - uint32_t idx_r = reg_ptr2idx(s, (void *)addr_align); + uint32_t idx_r = src2rvidx(s, (void *)addr_align); spm(sw, idx_r, SPM_X86_REG); if (len == 1) spm(sb, idx_src1, SPM_X86_REG + ((uintptr_t)addr & 1)); @@ -318,21 +305,42 @@ make_rtl(host_sm, void *addr, const rtlreg_t *src1, int len) { else assert(0); spm(lwu, idx_r, SPM_X86_REG); } +#else +make_rtl(host_lm, rtlreg_t* dest, const void *addr, int len) { + panic("only used in x86\n"); +} + +make_rtl(host_sm, void *addr, const rtlreg_t *src1, int len) { + panic("only used in x86\n"); +} +#endif + // we use tmp0 to store x86.pc of the next basic block make_rtl(j, vaddr_t target) { - if (!load_imm_big(tmp0, target)) rv64_addiw(tmp0, tmp0, target & 0xfff); +#ifdef REG_SPILLING + spill_writeback_all(); +#endif + load_imm(tmp0, target); tran_next_pc = NEXT_PC_JMP; } make_rtl(jr, rtlreg_t *target) { - rv64_addi(tmp0, reg_ptr2idx(s, target), 0); + uint32_t rvidx = src2rvidx(s, target); + rv64_addi(tmp0, rvidx, 0); +#ifdef REG_SPILLING + spill_writeback_all(); +#endif tran_next_pc = NEXT_PC_JMP; } make_rtl(jrelop, uint32_t relop, const rtlreg_t *src1, const rtlreg_t *src2, vaddr_t target) { - uint32_t rs1 = reg_ptr2idx(s, src1); - uint32_t rs2 = reg_ptr2idx(s, src2); + uint32_t ret = rtlreg2rvidx_pair(s, src1, true, src2, true); + uint32_t rs1 = ret >> 16; + uint32_t rs2 = ret & 0xffff; +#ifdef REG_SPILLING + spill_writeback_all(); +#endif uint32_t offset = 12; // branch two instructions extern int trans_buffer_index; int old_idx = trans_buffer_index; diff --git a/src/engine/rv64/spill.c b/src/engine/rv64/spill.c new file mode 100644 index 0000000000000000000000000000000000000000..3f09990117d86b71a46709e13dcdca0eebb181c5 --- /dev/null +++ b/src/engine/rv64/spill.c @@ -0,0 +1,165 @@ +#include "spill.h" +#include "tran.h" +#include "rv64-backend/rv_ins_def.h" +#include "rtl/rtl.h" + +#define TMP_REG_NUM 2 + +typedef struct { + uint32_t rvidx; + uint32_t spmidx; + bool dirty; +} Tmp_reg; +static Tmp_reg tmp_regs[TMP_REG_NUM]; + +void spill_init() { + assert(TMP_REG_NUM == 2); + tmp_regs[0].rvidx = tmp_reg1; + tmp_regs[1].rvidx = tmp_reg2; +} + +void spill_flush(int tmpidx) { + tmp_regs[tmpidx].spmidx = 0; + tmp_regs[tmpidx].dirty = 0; +} + +void spill_reset() { + spill_flush(0); + spill_flush(1); +} + +int spmidx2tmpidx(uint32_t spmidx) { + if (tmp_regs[0].spmidx == spmidx) return 0; + if (tmp_regs[1].spmidx == spmidx) return 1; + return -1; +} + +int rvidx2tmpidx(uint32_t rvidx) { + if (tmp_regs[0].rvidx == rvidx) return 0; + if (tmp_regs[1].rvidx == rvidx) return 1; + return -1; +} + +uint32_t spmidx2rvidx(uint32_t spmidx) { + int tmpidx = spmidx2tmpidx(spmidx); + if (tmpidx == -1) return 0; + return tmp_regs[tmpidx].rvidx; +} + +uint32_t varidx2rvidx(uint32_t varidx) { + if (varidx & ~SPMIDX_MASK) return varidx; + int tmpidx = spmidx2tmpidx(varidx); + assert(tmpidx != -1); + return tmp_regs[tmpidx].rvidx; +} + +void spill_writeback(uint32_t i) { + if (tmp_regs[i].spmidx != 0 && tmp_regs[i].dirty) { + spm(sw, tmp_regs[i].rvidx, 4 * (tmp_regs[i].spmidx & ~SPMIDX_MASK)); + tmp_regs[i].dirty = false; + } +} + +void spill_writeback_all() { + spill_writeback(0); + spill_writeback(1); +} + +// replace tmp_regs[tmpidx] with spmidx +void spill_replace(uint32_t tmpidx, uint32_t spmidx, int load_val) { + spill_writeback(tmpidx); + if (load_val) spm(lw, tmp_regs[tmpidx].rvidx, 4 * (spmidx & ~SPMIDX_MASK)); + + tmp_regs[tmpidx].spmidx = spmidx; + tmp_regs[tmpidx].dirty = false; +} + +// find a clean tmpreg and map it to spmidx +uint32_t spill_alloc(uint32_t spmidx, int load_val) { + uint32_t tmpidx = (tmp_regs[1].dirty ? 0 : 1); + spill_replace(tmpidx, spmidx, load_val); + return tmpidx; +} + +uint32_t rtlreg2varidx(DecodeExecState *s, const rtlreg_t* dest); + +static uint32_t rtlreg2rvidx_internal(DecodeExecState *s, const rtlreg_t *r, int is_dest) { + uint32_t varidx = rtlreg2varidx(s, r); + if (varidx & SPMIDX_MASK) { + uint32_t tmpidx = spmidx2tmpidx(varidx); + if (tmpidx == -1) tmpidx = spill_alloc(varidx, !is_dest); + varidx = tmp_regs[tmpidx].rvidx; + tmp_regs[tmpidx].dirty = is_dest; + } + return varidx; +} + +uint32_t src2rvidx(DecodeExecState *s, const rtlreg_t *src) { + return rtlreg2rvidx_internal(s, src, false); +} + +uint32_t dest2rvidx(DecodeExecState *s, const rtlreg_t *dest) { + return rtlreg2rvidx_internal(s, dest, true); +} + +uint32_t rtlreg2rvidx_pair(DecodeExecState *s, + const rtlreg_t *src1, int load_src1, const rtlreg_t *src2, int load_src2) { + uint32_t src1_varidx = rtlreg2varidx(s, src1); + uint32_t src2_varidx = rtlreg2varidx(s, src2); + + if ((src1_varidx & SPMIDX_MASK) && (src2_varidx & SPMIDX_MASK)) { + // check whether they are already mapped + uint32_t src1_tmpidx = spmidx2tmpidx(src1_varidx); + uint32_t src2_tmpidx = spmidx2tmpidx(src2_varidx); + + if (src1_tmpidx == -1 && src2_tmpidx != -1) { + src1_tmpidx = !src2_tmpidx; + spill_replace(src1_tmpidx, src1_varidx, load_src1); + } else if (src1_tmpidx != -1 && src2_tmpidx == -1) { + src2_tmpidx = !src1_tmpidx; + spill_replace(src2_tmpidx, src2_varidx, load_src2); + } else if (src1_tmpidx == -1 && src2_tmpidx == -1) { + src1_tmpidx = 0; + src2_tmpidx = 1; + spill_replace(src1_tmpidx, src1_varidx, load_src1); + spill_replace(src2_tmpidx, src2_varidx, load_src2); + } + + src1_varidx = tmp_regs[src1_tmpidx].rvidx; + src2_varidx = tmp_regs[src2_tmpidx].rvidx; + } else if (src1_varidx & SPMIDX_MASK) { + uint32_t src1_tmpidx = spmidx2tmpidx(src1_varidx); + if (src1_tmpidx == -1) src1_tmpidx = spill_alloc(src1_varidx, load_src1); + src1_varidx = tmp_regs[src1_tmpidx].rvidx; + } else if (src2_varidx & SPMIDX_MASK) { + uint32_t src2_tmpidx = spmidx2tmpidx(src2_varidx); + if (src2_tmpidx == -1) src2_tmpidx = spill_alloc(src2_varidx, load_src2); + src2_varidx = tmp_regs[src2_tmpidx].rvidx; + } + + return (src1_varidx << 16) | src2_varidx; +} + +void spill_set_dirty(uint32_t tmpidx) { + tmp_regs[tmpidx].dirty = true; +} + +void spill_set_dirty_rvidx(uint32_t rvidx) { + int tmpidx = rvidx2tmpidx(rvidx); + if (tmpidx != -1) spill_set_dirty(tmpidx); +} + +// this will be called after every translation of an instruction +// to flush RTL tmp registers, since their life-cycle is only +// valid during the translation of a single instruction +static void spill_flush_local_internal(DecodeExecState *s, const rtlreg_t *dest) { + uint32_t varidx = rtlreg2varidx(s, dest); + if (tmp_regs[0].spmidx == varidx && tmp_regs[0].dirty) spill_flush(0); + if (tmp_regs[1].spmidx == varidx && tmp_regs[1].dirty) spill_flush(1); +} +void spill_flush_local() { + DecodeExecState state; // only used in rtlreg2varidx() + DecodeExecState *s = &state; + spill_flush_local_internal(s, s0); + spill_flush_local_internal(s, s1); +} diff --git a/src/engine/rv64/spill.h b/src/engine/rv64/spill.h new file mode 100644 index 0000000000000000000000000000000000000000..9d5fddad36aaba9678afe91b6018a67502130985 --- /dev/null +++ b/src/engine/rv64/spill.h @@ -0,0 +1,20 @@ +#ifndef __SPILL_H__ +#define __SPILL_H__ + +#include +#include + +uint32_t spmidx2rvidx(uint32_t); +uint32_t spill_out_and_remap(DecodeExecState*, uint32_t); +void spill_flush_all(); +void cal_suffix_inst(); +void spill_writeback_all(); +void spill_set_spmidx(uint32_t tmpidx, uint32_t new_spmidx); +int rvidx2tmpidx(uint32_t rvidx); +void spill_set_dirty_rvidx(uint32_t rvidx); +uint32_t varidx2rvidx(uint32_t varidx); +void spill_set_dirty(uint32_t tmpidx); +void spill_writeback(uint32_t i); +uint32_t rtlreg2rvidx_pair(DecodeExecState *s, const rtlreg_t *src1, int load_src1, const rtlreg_t *src2, int load_src2); + +#endif diff --git a/src/engine/rv64/tran.c b/src/engine/rv64/tran.c index a8d8d34eaafb17dceb8af5b93dd93f60f79c271b..4c2d97ca0e185935d7189c1aaa15c011d9d6742f 100644 --- a/src/engine/rv64/tran.c +++ b/src/engine/rv64/tran.c @@ -17,6 +17,8 @@ static void clear_trans_buffer() { trans_buffer_index = 0; } void asm_print(vaddr_t ori_pc, int instr_len, bool print_flag); vaddr_t rv64_exec_trans_buffer(void *buf, int nr_instr, int npc_type); void guest_getregs(CPU_state *cpu); +void spill_reset(); +void spill_flush_local(); typedef struct TB { vaddr_t pc; @@ -94,6 +96,7 @@ void mainloop() { TB *tb = find_tb(tb_start); if (tb == NULL) { clear_trans_buffer(); + spill_reset(); tran_next_pc = NEXT_PC_SEQ; int guest_nr_instr = 0; while (1) { @@ -101,6 +104,8 @@ void mainloop() { __attribute__((unused)) vaddr_t seq_pc = isa_exec_once(); guest_nr_instr ++; + spill_flush_local(); + if (nemu_state.state != NEMU_RUNNING) tran_next_pc = NEXT_PC_END; #ifdef DEBUG diff --git a/src/engine/rv64/tran.h b/src/engine/rv64/tran.h index 5e88d16230d8d78b6204e31f310a4229ce1840b0..7563921cb9e614f958e331b17fc058624fc4fe74 100644 --- a/src/engine/rv64/tran.h +++ b/src/engine/rv64/tran.h @@ -13,19 +13,34 @@ extern void (*backend_exec)(uint64_t n); #define BBL_MAX_SIZE (16 * 1024) -// scratch pad memory, whose address space is [0, 64) -#define spm(op, reg, offset) concat(rv64_, op)(reg, x0, offset) +// There are 4 types of indices. +// * rvidx - the index of rv64 register, can be zero. +// used to construct rv instructions +// * spmidx - the index of variable in SPM masked with SPM_IDX_MASK, which is non-zero. +// used to allocate rtl registers which can not be mapped to rv64 registers +// * varidx - (mapped_to_spm ? smpidx : rvidx) +// * tmpidx - the index of record of temporal registers in spill.c + +#define SPMIDX_MASK 0x20 + +// scratch pad memory, whose address space is [riscv64_PMEM_BASE, riscv64_PMEM_BASE + 64) +#define spm(op, reg, offset) concat(rv64_, op)(reg, spm_base, offset) #define SPM_X86_REG 0 // x86 byte/word register write enum { x0 = 0 }; // static register allocation #if defined(__ISA_x86__) -enum { tmp0 = 30, mask32 = 24, mask16 = 25 }; +enum { tmp0 = 30, mask32 = 24, mask16 = 25, spm_base = 0, tmp_reg1 = 0, tmp_reg2 = 0 }; #elif defined(__ISA_mips32__) -enum { tmp0 = 1, mask32 = 28, mask16 = 0 }; +enum { tmp0 = 1, mask32 = 28, mask16 = 0, spm_base = 25, tmp_reg1 = 26, tmp_reg2 = 27 }; +#define REG_SPILLING #elif defined(__ISA_riscv32__) -enum { tmp0 = 3, mask32 = 4, mask16 = 0 }; +enum { tmp0 = 31, mask32 = 27, mask16 = 0, spm_base = 26, tmp_reg1 = 3, tmp_reg2 = 4 }; +#define REG_SPILLING +#elif defined(__ISA_riscv64__) +enum { tmp0 = 31, mask32 = 0, mask16 = 0, spm_base = 27, tmp_reg1 = 3, tmp_reg2 = 4 }; +#define REG_SPILLING #endif #endif diff --git a/src/isa/riscv64/exec/compute.h b/src/isa/riscv64/exec/compute.h index b95c95a62320136cecf48ecfb00d90101da51c45..091bc45a4038c8754dd47b4687bf69ab41b127cc 100644 --- a/src/isa/riscv64/exec/compute.h +++ b/src/isa/riscv64/exec/compute.h @@ -145,7 +145,7 @@ static inline make_EHelper(srlw) { } else { // srlw - rtl_andi(s, s1, dsrc1, 0xffffffffu); + rtl_zext(s, s1, dsrc1, 4); rtl_shr(s, s0, s1, s0); print_asm_template3(srlw); } @@ -178,7 +178,7 @@ static inline make_EHelper(srliw) { } else { // srlw - rtl_andi(s, s0, dsrc1, 0xffffffffu); + rtl_zext(s, s0, dsrc1, 4); rtl_shri(s, s0, s0, id_src2->imm & 0x1f); print_asm_template3(srliw); } diff --git a/src/isa/riscv64/exec/muldiv.h b/src/isa/riscv64/exec/muldiv.h index 2de209b63becabc67949faa27a8dbcabeb6821a1..d64b6a6122f5b6ca00403ae9c4bb76052cf16628 100644 --- a/src/isa/riscv64/exec/muldiv.h +++ b/src/isa/riscv64/exec/muldiv.h @@ -37,45 +37,45 @@ static inline make_EHelper(mulhsu) { } static inline make_EHelper(div) { - if (*dsrc2 == 0) { - rtl_li(s, ddest, ~0lu); - } else if (*dsrc1 == 0x8000000000000000LL && *dsrc2 == -1) { - rtl_mv(s, ddest, dsrc1); - } else { + //if (*dsrc2 == 0) { + // rtl_li(s, ddest, ~0lu); + //} else if (*dsrc1 == 0x8000000000000000LL && *dsrc2 == -1) { + // rtl_mv(s, ddest, dsrc1); + //} else { rtl_idiv_q(s, ddest, dsrc1, dsrc2); - } + //} print_asm_template3(div); } static inline make_EHelper(divu) { - if (*dsrc2 == 0) { - rtl_li(s, ddest, ~0lu); - } else { + //if (*dsrc2 == 0) { + // rtl_li(s, ddest, ~0lu); + //} else { rtl_div_q(s, ddest, dsrc1, dsrc2); - } + //} print_asm_template3(divu); } static inline make_EHelper(rem) { - if (*dsrc2 == 0) { - rtl_mv(s, ddest, dsrc1); - } else if (*dsrc1 == 0x8000000000000000LL && *dsrc2 == -1) { - rtl_mv(s, ddest, rz); - } else { + //if (*dsrc2 == 0) { + // rtl_mv(s, ddest, dsrc1); + //} else if (*dsrc1 == 0x8000000000000000LL && *dsrc2 == -1) { + // rtl_mv(s, ddest, rz); + //} else { rtl_idiv_r(s, ddest, dsrc1, dsrc2); - } + //} print_asm_template3(rem); } static inline make_EHelper(remu) { - if (*dsrc2 == 0) { - rtl_mv(s, ddest, dsrc1); - } else { + //if (*dsrc2 == 0) { + // rtl_mv(s, ddest, dsrc1); + //} else { rtl_div_r(s, ddest, dsrc1, dsrc2); - } + //} print_asm_template3(remu); } @@ -89,13 +89,13 @@ static inline make_EHelper(mulw) { static inline make_EHelper(divw) { rtl_sext(s, s0, dsrc1, 4); rtl_sext(s, s1, dsrc2, 4); - if (*s1 == 0) { - rtl_li(s, s0, ~0lu); - } else if (*s0 == 0x80000000 && *s1 == -1) { - //rtl_mv(s, s0, s0); - } else { + //if (*s1 == 0) { + // rtl_li(s, s0, ~0lu); + //} else if (*s0 == 0x80000000 && *s1 == -1) { + // //rtl_mv(s, s0, s0); + //} else { rtl_idiv_q(s, s0, s0, s1); - } + //} rtl_sext(s, ddest, s0, 4); print_asm_template3(divw); @@ -104,39 +104,39 @@ static inline make_EHelper(divw) { static inline make_EHelper(remw) { rtl_sext(s, s0, dsrc1, 4); rtl_sext(s, s1, dsrc2, 4); - if (*s1 == 0) { - //rtl_mv(s, s0, s0); - } else if (*s0 == 0x80000000 && *s1 == -1) { - rtl_mv(s, s0, rz); - } else { + //if (*s1 == 0) { + // //rtl_mv(s, s0, s0); + //} else if (*s0 == 0x80000000 && *s1 == -1) { + // rtl_mv(s, s0, rz); + //} else { rtl_idiv_r(s, s0, s0, s1); - } + //} rtl_sext(s, ddest, s0, 4); print_asm_template3(remw); } static inline make_EHelper(divuw) { - rtl_andi(s, s0, dsrc1, 0xffffffffu); - rtl_andi(s, s1, dsrc2, 0xffffffffu); - if (*s1 == 0) { - rtl_li(s, s0, ~0lu); - } else { + rtl_zext(s, s0, dsrc1, 4); + rtl_zext(s, s1, dsrc2, 4); + //if (*s1 == 0) { + // rtl_li(s, s0, ~0lu); + //} else { rtl_div_q(s, s0, s0, s1); - } + //} rtl_sext(s, ddest, s0, 4); print_asm_template3(divuw); } static inline make_EHelper(remuw) { - rtl_andi(s, s0, dsrc1, 0xffffffffu); - rtl_andi(s, s1, dsrc2, 0xffffffffu); - if (*s1 == 0) { - //rtl_mv(s, s0, s0); - } else { + rtl_zext(s, s0, dsrc1, 4); + rtl_zext(s, s1, dsrc2, 4); + //if (*s1 == 0) { + // //rtl_mv(s, s0, s0); + //} else { rtl_div_r(s, s0, s0, s1); - } + //} rtl_sext(s, ddest, s0, 4); print_asm_template3(remuw); diff --git a/src/monitor/debug/ui.c b/src/monitor/debug/ui.c index 371b670b9234e8707442838074a2ad87267121ef..a2306f2c101edb872f549e3b3364fc3f326a12ea 100644 --- a/src/monitor/debug/ui.c +++ b/src/monitor/debug/ui.c @@ -186,8 +186,9 @@ static int cmd_load(char *args) { else { FILE *fp = fopen(arg, "r"); assert(fp != NULL); - fread(&cpu, sizeof(cpu), 1, fp); - fread(guest_to_host(0), PMEM_SIZE, 1, fp); + __attribute__((unused)) int ret; + ret = fread(&cpu, sizeof(cpu), 1, fp); + ret = fread(guest_to_host(0), PMEM_SIZE, 1, fp); fclose(fp); } return 0;