From a56f711558dca293168fb4098dc1a4f7a4ba6b77 Mon Sep 17 00:00:00 2001 From: Zihao Yu Date: Fri, 17 Apr 2020 10:53:52 +0800 Subject: [PATCH] engine,rv64,spill: only writeback dirty tmp to SPM --- src/engine/rv64/rv64-backend/rtl-basic.c | 13 +++++- src/engine/rv64/spill.c | 58 +++++++++++++++++++----- src/engine/rv64/spill.h | 6 +++ 3 files changed, 63 insertions(+), 14 deletions(-) diff --git a/src/engine/rv64/rv64-backend/rtl-basic.c b/src/engine/rv64/rv64-backend/rtl-basic.c index 7f889e8e..37607a4e 100644 --- a/src/engine/rv64/rv64-backend/rtl-basic.c +++ b/src/engine/rv64/rv64-backend/rtl-basic.c @@ -68,6 +68,7 @@ static inline void load_imm_no_opt(uint32_t r, const sword_t imm) { rtl_kill(s, src1); \ uint32_t dest_rvidx = rtlreg2rvidx(s, dest); \ rv64_addi(dest_rvidx, tmp0, 0); \ + spill_set_dirty_rvidx(dest_rvidx); \ } \ else concat(rv64_, rv64_name) (dest_varidx, src1_rvidx, src2_rvidx); \ } @@ -86,6 +87,7 @@ static inline void load_imm_no_opt(uint32_t r, const sword_t imm) { uint32_t dest_rvidx = rtlreg2rvidx(s, dest); \ uint32_t src1_rvidx = rtlreg2rvidx(s, src1); \ 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) \ @@ -95,6 +97,7 @@ static inline void load_imm_no_opt(uint32_t r, const sword_t imm) { 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) @@ -140,6 +143,7 @@ make_rtl(setrelop, uint32_t relop, rtlreg_t *dest, const rtlreg_t *src1, const r rtl_kill(s, src1); uint32_t dest_rvidx = rtlreg2rvidx(s, dest); rv64_addi(dest_rvidx, tmp0, 0); + spill_set_dirty_rvidx(dest_rvidx); } else rv64_relop(relop, dest_varidx, src1_rvidx, src2_rvidx); } @@ -158,13 +162,15 @@ make_rtl(setrelopi, uint32_t relop, rtlreg_t *dest, const rtlreg_t *src1, const uint32_t idx_src1 = rtlreg2rvidx(s, src1); 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(idx_dest, idx_src1, imm); goto finish; + case RELOP_LTU: rv64_sltiu(idx_dest, idx_src1, imm); goto finish; // fall through for default cases } } if (!big_imm) rv64_addiw(tmp0, x0, imm); rv64_relop(relop, idx_dest, idx_src1, tmp0); +finish: + spill_set_dirty_rvidx(idx_dest); } @@ -193,6 +199,7 @@ make_rtl(mul_hi, rtlreg_t* dest, const rtlreg_t* src1, const rtlreg_t* src2) { uint32_t idx_dest = rtlreg2rvidx(s, dest); rv64_addi(idx_dest, tmp0, 0); rv64_srai(idx_dest, idx_dest, 32); + spill_set_dirty_rvidx(idx_dest); } make_rtl(imul_hi, rtlreg_t* dest, const rtlreg_t* src1, const rtlreg_t* src2) { @@ -205,6 +212,7 @@ make_rtl(imul_hi, rtlreg_t* dest, const rtlreg_t* src1, const rtlreg_t* src2) { uint32_t idx_dest = rtlreg2rvidx(s, dest); rv64_addi(idx_dest, tmp0, 0); rv64_srai(idx_dest, idx_dest, 32); + spill_set_dirty_rvidx(idx_dest); } #else make_rtl(mul_hi, rtlreg_t* dest, const rtlreg_t* src1, const rtlreg_t* src2) { @@ -322,6 +330,7 @@ make_rtl(lm, rtlreg_t *dest, const rtlreg_t* addr, const sword_t imm, int len) { case 8: rv64_ld (idx_dest, tmp0, imm & 0xfff); break; default: assert(0); } + spill_set_dirty_rvidx(idx_dest); } make_rtl(sm, const rtlreg_t* addr, const sword_t imm, const rtlreg_t* src1, int len) { diff --git a/src/engine/rv64/spill.c b/src/engine/rv64/spill.c index b5869a78..6493965f 100644 --- a/src/engine/rv64/spill.c +++ b/src/engine/rv64/spill.c @@ -4,9 +4,9 @@ #include "rtl/rtl.h" typedef struct { - uint32_t rvidx; - uint32_t spmidx; - bool used; + uint32_t rvidx; + uint32_t spmidx; + bool used, dirty; } Tmp_reg; static Tmp_reg tmp_regs[TMP_REG_NUM]; @@ -17,25 +17,45 @@ void tmp_regs_init() { } void tmp_regs_reset() { - tmp_regs[0].used = 0; tmp_regs[0].spmidx = 0; + tmp_regs[0].used = 0; + tmp_regs[0].dirty = 0; tmp_regs[1].spmidx = 0; - tmp_regs[1].used = 0; + tmp_regs[1].dirty = 0; } -uint32_t spmidx2rvidx(uint32_t spmidx) { +int spmidx2tmpidx(uint32_t spmidx) { for (int i = 0; i < TMP_REG_NUM; i++) { - if (tmp_regs[i].spmidx == spmidx) { - tmp_regs[i].used = 1; - return tmp_regs[i].rvidx; - } + if (tmp_regs[i].spmidx == spmidx) return i; + } + return -1; +} + +int rvidx2tmpidx(uint32_t rvidx) { + for (int i = 0; i < TMP_REG_NUM; i++) { + if (tmp_regs[i].rvidx == rvidx) return i; } - return 0; + return -1; +} + +uint32_t spmidx2rvidx(uint32_t spmidx) { + int tmpidx = spmidx2tmpidx(spmidx); + if (tmpidx == -1) return 0; + tmp_regs[tmpidx].used = 1; + 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) { + 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; } } @@ -73,6 +93,20 @@ uint32_t spill_out_and_remap(DecodeExecState *s, uint32_t spmidx) { tmp_regs[tmpidx].spmidx = spmidx; tmp_regs[tmpidx].used = 1; + tmp_regs[tmpidx].dirty = false; return tmp_regs[tmpidx].rvidx; } + +void spill_set_spmidx(uint32_t tmpidx, uint32_t new_spmidx) { + tmp_regs[tmpidx].spmidx = new_spmidx; +} + +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); +} diff --git a/src/engine/rv64/spill.h b/src/engine/rv64/spill.h index fa9b20af..f4b867ae 100644 --- a/src/engine/rv64/spill.h +++ b/src/engine/rv64/spill.h @@ -21,5 +21,11 @@ void spill_flush(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); #endif -- GitLab