From a107902ca07e69413437fd2e66495a91b4b6fb18 Mon Sep 17 00:00:00 2001 From: Pavel Pisa Date: Mon, 4 Feb 2019 18:39:16 +0100 Subject: Take into account actual requirements for rs, rt and rd write for individual instructions. Signed-off-by: Pavel Pisa --- qtmips_machine/core.cpp | 21 ++++++++++----------- qtmips_machine/core.h | 2 ++ qtmips_machine/instruction.cpp | 25 +++++++++++++++---------- 3 files changed, 27 insertions(+), 21 deletions(-) (limited to 'qtmips_machine') diff --git a/qtmips_machine/core.cpp b/qtmips_machine/core.cpp index fd37d6b..d91a36e 100644 --- a/qtmips_machine/core.cpp +++ b/qtmips_machine/core.cpp @@ -153,6 +153,8 @@ struct Core::dtDecode Core::decode(const struct dtFetch &dt) { .regd = regd, .regd31 = regd31, .regwrite = regwrite, + .alu_req_rs = flags & IMF_ALU_REQ_RS, + .alu_req_rt = flags & IMF_ALU_REQ_RT, .bjr_req_rs = bjr_req_rs, .bjr_req_rt = bjr_req_rt, .forward_m_d_rs = false, @@ -401,23 +403,21 @@ void CorePipelined::do_step() { // Note: We make exception with $0 as that has no effect when written and is used in nop instruction #define HAZARD(STAGE) ( \ - (STAGE).regwrite && (STAGE).rwrite != 0 && \ - ((STAGE).rwrite == dt_d.inst.rs() || ( \ - (dt_d.inst.type() == Instruction::T_R || dt_d.inst.is_store()) && \ - (STAGE).rwrite == dt_d.inst.rt()) \ - )) // Note: We make exception with $0 as that has no effect and is used in nop instruction + (STAGE).regwrite && (STAGE).rwrite != 0 && \ + ((dt_d.alu_req_rs && (STAGE).rwrite == dt_d.inst.rs()) || \ + (dt_d.alu_req_rt && (STAGE).rwrite == dt_d.inst.rt())) \ + ) // Note: We make exception with $0 as that has no effect and is used in nop instruction // Write back stage combinatoricly propagates written instruction to decode stage so nothing has to be done for that stage if (HAZARD(dt_m)) { // Hazard with instruction in memory stage if (hazard_unit == MachineConfig::HU_STALL_FORWARD) { // Forward result value - if (dt_m.rwrite == dt_d.inst.rs()) { + if (dt_d.alu_req_rs && dt_m.rwrite == dt_d.inst.rs()) { dt_d.val_rs = dt_m.towrite_val; dt_d.ff_rs = FORWARD_FROM_M; } - if ((dt_d.inst.type() == Instruction::T_R || dt_d.inst.is_store()) && - (dt_m.rwrite == dt_d.inst.rt())) { + if (dt_d.alu_req_rt && dt_m.rwrite == dt_d.inst.rt()) { dt_d.val_rt = dt_m.towrite_val; dt_d.ff_rt = FORWARD_FROM_M; } @@ -431,12 +431,11 @@ void CorePipelined::do_step() { stall = true; else { // Forward result value - if (dt_e.rwrite == dt_d.inst.rs()) { + if (dt_d.alu_req_rs && dt_e.rwrite == dt_d.inst.rs()) { dt_d.val_rs = dt_e.alu_val; dt_d.ff_rs = FORWARD_FROM_W; } - if ((dt_d.inst.type() == Instruction::T_R || dt_d.inst.is_store()) && - (dt_e.rwrite == dt_d.inst.rt())) { + if (dt_d.alu_req_rt && dt_e.rwrite == dt_d.inst.rt()) { dt_d.val_rt = dt_e.alu_val; dt_d.ff_rt = FORWARD_FROM_W; } diff --git a/qtmips_machine/core.h b/qtmips_machine/core.h index 3a27f55..6f9509f 100644 --- a/qtmips_machine/core.h +++ b/qtmips_machine/core.h @@ -132,6 +132,8 @@ protected: bool regd; // If rd is used (otherwise rt is used for write target) bool regd31; // Use R31 as destionation for JAL bool regwrite; // If output should be written back to register (which one depends on regd) + bool alu_req_rs; // requires rs value for ALU + bool alu_req_rt; // requires rt value for ALU or SW bool bjr_req_rs; // requires rs for beq, bne, blez, bgtz, jr nad jalr bool bjr_req_rt; // requires rt for beq, bne bool forward_m_d_rs; // forwarding required for beq, bne, blez, bgtz, jr nad jalr diff --git a/qtmips_machine/instruction.cpp b/qtmips_machine/instruction.cpp index 9a7b9c9..4c91d6f 100644 --- a/qtmips_machine/instruction.cpp +++ b/qtmips_machine/instruction.cpp @@ -40,8 +40,13 @@ using namespace machine; -#define FLAGS_ALU_I (IMF_SUPPORTED | IMF_ALUSRC | IMF_REGWRITE) -#define FLAGS_ALU_I_ZE (IMF_SUPPORTED | IMF_ALUSRC | IMF_REGWRITE | IMF_ZERO_EXTEND) +#define FLAGS_ALU_I (IMF_SUPPORTED | IMF_ALUSRC | IMF_REGWRITE | IMF_ALU_REQ_RS) +#define FLAGS_ALU_I_ZE (FLAGS_ALU_I | IMF_ZERO_EXTEND) + +#define FLAGS_ALU_I_LOAD (IMF_SUPPORTED | IMF_ALUSRC | IMF_REGWRITE | \ + IMF_MEMREAD | IMF_MEM | IMF_ALU_REQ_RS) +#define FLAGS_ALU_I_STORE (IMF_SUPPORTED | IMF_ALUSRC | IMF_MEMWRITE | \ + IMF_MEM | IMF_MEM_STORE | IMF_ALU_REQ_RS | IMF_ALU_REQ_RT) #define FLAGS_ALU_T_R (IMF_SUPPORTED | IMF_REGD | IMF_REGWRITE) #define FLAGS_ALU_T_R_STD (IMF_SUPPORTED | IMF_REGD | IMF_REGWRITE \ @@ -119,28 +124,28 @@ static const struct InstructionMap instruction_map[] = { IM_UNKNOWN, // 30 IM_UNKNOWN, // 31 {"LB", IT_I, ALU_OP_ADDU, AC_BYTE, // LB - .flags = IMF_SUPPORTED | IMF_ALUSRC | IMF_REGWRITE | IMF_MEMREAD | IMF_MEM}, + .flags = FLAGS_ALU_I_LOAD}, {"LH", IT_I, ALU_OP_ADDU, AC_HALFWORD, // LH - .flags = IMF_SUPPORTED | IMF_ALUSRC | IMF_REGWRITE | IMF_MEMREAD | IMF_MEM}, + .flags = FLAGS_ALU_I_LOAD}, {"LWL", IT_I, ALU_OP_ADDU, NOMEM, // LWL - unsupported .flags = IMF_MEM}, {"LW", IT_I, ALU_OP_ADDU, AC_WORD, // LW - .flags = IMF_SUPPORTED | IMF_ALUSRC | IMF_REGWRITE | IMF_MEMREAD | IMF_MEM}, + .flags = FLAGS_ALU_I_LOAD}, {"LBU", IT_I, ALU_OP_ADDU, AC_BYTE_UNSIGNED, // LBU - .flags = IMF_SUPPORTED | IMF_ALUSRC | IMF_REGWRITE | IMF_MEMREAD | IMF_MEM }, + .flags = FLAGS_ALU_I_LOAD}, {"LHU", IT_I, ALU_OP_ADDU, AC_HALFWORD_UNSIGNED, // LHU - .flags = IMF_SUPPORTED | IMF_ALUSRC | IMF_REGWRITE | IMF_MEMREAD | IMF_MEM,}, + .flags = FLAGS_ALU_I_LOAD}, {"LWR", IT_I, ALU_OP_ADDU, NOMEM, // LWR - unsupported .flags = IMF_MEM}, IM_UNKNOWN, // 39 {"SB", IT_I, ALU_OP_ADDU, AC_BYTE, // SB - .flags = IMF_SUPPORTED | IMF_ALUSRC | IMF_MEMWRITE | IMF_MEM | IMF_MEM_STORE}, + .flags = FLAGS_ALU_I_STORE}, {"SH", IT_I, ALU_OP_ADDU, AC_HALFWORD, // SH - .flags = IMF_SUPPORTED | IMF_ALUSRC | IMF_MEMWRITE | IMF_MEM | IMF_MEM_STORE}, + .flags = FLAGS_ALU_I_STORE}, {"SWL", IT_I, ALU_OP_ADDU, NOMEM, // SWL .flags = IMF_MEM | IMF_MEM_STORE}, {"SW", IT_I, ALU_OP_ADDU, AC_WORD, // SW - .flags = IMF_SUPPORTED | IMF_ALUSRC | IMF_MEMWRITE | IMF_MEM | IMF_MEM_STORE}, + .flags = FLAGS_ALU_I_STORE}, IM_UNKNOWN, // 44,NOPE, // 44 IM_UNKNOWN, // 45,NOPE, // 45 {"SWR", IT_I, ALU_OP_ADDU, NOMEM, // SWR -- cgit v1.2.3