diff --git a/riscv/decode_macros.h b/riscv/decode_macros.h index 0f32a3a10..1aa74fb86 100644 --- a/riscv/decode_macros.h +++ b/riscv/decode_macros.h @@ -22,6 +22,7 @@ #define RS2 READ_REG(insn.rs2()) #define RS3 READ_REG(insn.rs3()) #define WRITE_RD(value) WRITE_REG(insn.rd(), value) +#define CHECK_RD() CHECK_REG(insn.rd()) /* 0 : int * 1 : floating @@ -30,9 +31,9 @@ * 4 : csr */ #define WRITE_REG(reg, value) ({ \ + CHECK_REG(reg); \ reg_t wdata = (value); /* value may have side effects */ \ if (DECODE_MACRO_USAGE_LOGGED) STATE.log_reg_write[(reg) << 4] = {wdata, 0}; \ - CHECK_REG(reg); \ STATE.XPR.write(reg, wdata); \ }) #define WRITE_FREG(reg, value) ({ \ diff --git a/riscv/insn_template.cc b/riscv/insn_template.cc index 9194d19f4..168e2dc83 100644 --- a/riscv/insn_template.cc +++ b/riscv/insn_template.cc @@ -5,24 +5,29 @@ #define DECODE_MACRO_USAGE_LOGGED 0 +#define PROLOGUE \ + reg_t npc = sext_xlen(pc + insn_length(OPCODE)) + +#define EPILOGUE \ + trace_opcode(p, OPCODE, insn); \ + return npc + reg_t fast_rv32i_NAME(processor_t* p, insn_t insn, reg_t pc) { #define xlen 32 - reg_t npc = sext_xlen(pc + insn_length(OPCODE)); + PROLOGUE; #include "insns/NAME.h" - trace_opcode(p, OPCODE, insn); + EPILOGUE; #undef xlen - return npc; } reg_t fast_rv64i_NAME(processor_t* p, insn_t insn, reg_t pc) { #define xlen 64 - reg_t npc = sext_xlen(pc + insn_length(OPCODE)); + PROLOGUE; #include "insns/NAME.h" - trace_opcode(p, OPCODE, insn); + EPILOGUE; #undef xlen - return npc; } #undef DECODE_MACRO_USAGE_LOGGED @@ -31,21 +36,19 @@ reg_t fast_rv64i_NAME(processor_t* p, insn_t insn, reg_t pc) reg_t logged_rv32i_NAME(processor_t* p, insn_t insn, reg_t pc) { #define xlen 32 - reg_t npc = sext_xlen(pc + insn_length(OPCODE)); + PROLOGUE; #include "insns/NAME.h" - trace_opcode(p, OPCODE, insn); + EPILOGUE; #undef xlen - return npc; } reg_t logged_rv64i_NAME(processor_t* p, insn_t insn, reg_t pc) { #define xlen 64 - reg_t npc = sext_xlen(pc + insn_length(OPCODE)); + PROLOGUE; #include "insns/NAME.h" - trace_opcode(p, OPCODE, insn); + EPILOGUE; #undef xlen - return npc; } #undef CHECK_REG @@ -57,21 +60,19 @@ reg_t logged_rv64i_NAME(processor_t* p, insn_t insn, reg_t pc) reg_t fast_rv32e_NAME(processor_t* p, insn_t insn, reg_t pc) { #define xlen 32 - reg_t npc = sext_xlen(pc + insn_length(OPCODE)); + PROLOGUE; #include "insns/NAME.h" - trace_opcode(p, OPCODE, insn); + EPILOGUE; #undef xlen - return npc; } reg_t fast_rv64e_NAME(processor_t* p, insn_t insn, reg_t pc) { #define xlen 64 - reg_t npc = sext_xlen(pc + insn_length(OPCODE)); + PROLOGUE; #include "insns/NAME.h" - trace_opcode(p, OPCODE, insn); + EPILOGUE; #undef xlen - return npc; } #undef DECODE_MACRO_USAGE_LOGGED @@ -80,19 +81,17 @@ reg_t fast_rv64e_NAME(processor_t* p, insn_t insn, reg_t pc) reg_t logged_rv32e_NAME(processor_t* p, insn_t insn, reg_t pc) { #define xlen 32 - reg_t npc = sext_xlen(pc + insn_length(OPCODE)); + PROLOGUE; #include "insns/NAME.h" - trace_opcode(p, OPCODE, insn); + EPILOGUE; #undef xlen - return npc; } reg_t logged_rv64e_NAME(processor_t* p, insn_t insn, reg_t pc) { #define xlen 64 - reg_t npc = sext_xlen(pc + insn_length(OPCODE)); + PROLOGUE; #include "insns/NAME.h" - trace_opcode(p, OPCODE, insn); + EPILOGUE; #undef xlen - return npc; } diff --git a/riscv/insns/jal.h b/riscv/insns/jal.h index cd599641e..e7a75c78e 100644 --- a/riscv/insns/jal.h +++ b/riscv/insns/jal.h @@ -1,3 +1,4 @@ +CHECK_RD(); reg_t tmp = npc; set_pc(JUMP_TARGET); WRITE_RD(tmp); diff --git a/riscv/insns/jalr.h b/riscv/insns/jalr.h index 0606f6728..de84e891c 100644 --- a/riscv/insns/jalr.h +++ b/riscv/insns/jalr.h @@ -1,3 +1,4 @@ +CHECK_RD(); reg_t tmp = npc; set_pc((RS1 + insn.i_imm()) & ~reg_t(1)); WRITE_RD(tmp);