diff options
| author | Pavel Pisa <pisa@cmp.felk.cvut.cz> | 2019-02-08 14:41:41 +0100 | 
|---|---|---|
| committer | Pavel Pisa <pisa@cmp.felk.cvut.cz> | 2019-02-08 14:41:41 +0100 | 
| commit | 38674515b1629865be6aa271dbbcad1a8cc306a8 (patch) | |
| tree | 0948a94d26342a7d50c6f670dbadba33add3ff73 /qtmips_machine | |
| parent | bd11856c5915ef52ca3325a27fca07049ab2215a (diff) | |
| download | qtmips-38674515b1629865be6aa271dbbcad1a8cc306a8.tar.gz qtmips-38674515b1629865be6aa271dbbcad1a8cc306a8.tar.bz2 qtmips-38674515b1629865be6aa271dbbcad1a8cc306a8.zip  | |
Implement even deprecated BEQL, BNEL, BLEZL, BGTZL, BLTZL, BGEZL, BLTZALL, BGEZALL.
GCC generates these opcodes for default compilation mode.
Signed-off-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
Diffstat (limited to 'qtmips_machine')
| -rw-r--r-- | qtmips_machine/core.cpp | 24 | ||||
| -rw-r--r-- | qtmips_machine/core.h | 1 | ||||
| -rw-r--r-- | qtmips_machine/instruction.cpp | 28 | ||||
| -rw-r--r-- | qtmips_machine/instruction.h | 3 | 
4 files changed, 39 insertions, 17 deletions
diff --git a/qtmips_machine/core.cpp b/qtmips_machine/core.cpp index 2d33309..9312a69 100644 --- a/qtmips_machine/core.cpp +++ b/qtmips_machine/core.cpp @@ -189,6 +189,7 @@ struct Core::dtDecode Core::decode(const struct dtFetch &dt) {          .jump = flags & IMF_JUMP,          .bj_not = flags & IMF_BJ_NOT,          .bgt_blez = flags & IMF_BGTZ_BLEZ, +        .nb_skip_ds = flags & IMF_NB_SKIP_DS,          .forward_m_d_rs = false,          .forward_m_d_rt = false,          .aluop = alu_op, @@ -366,6 +367,10 @@ void Core::dtDecodeInit(struct dtDecode &dt) {      dt.regwrite = false;      dt.bjr_req_rs = false; // requires rs for beq, bne, blez, bgtz, jr nad jalr      dt.bjr_req_rt = false; // requires rt for beq, bne +    dt.jump = false; +    dt.bj_not = false; +    dt.bgt_blez = false; +    dt.nb_skip_ds = false;      dt.forward_m_d_rs = false;      dt.forward_m_d_rt = false;      dt.aluop = ALU_OP_SLL; @@ -423,17 +428,24 @@ void CoreSingle::do_step() {      struct dtFetch f = fetch();      struct dtDecode d = decode(f); -    struct dtExecute e = execute(d); -    struct dtMemory m = memory(e); -    writeback(m); +    // Handle PC before instruction following jump leaves decode stage      if (jmp_delay_decode != nullptr) {          in_delay_slot = handle_pc(*jmp_delay_decode); +        if (jmp_delay_decode->nb_skip_ds && !in_delay_slot) { +            // Discard processing of instruction in delay slot +            // for BEQL, BNEL, BLEZL, BGTZL, BLTZL, BGEZL, BLTZALL, BGEZALL +            dtDecodeInit(d); +        }          jump_branch_pc = jmp_delay_decode->inst_addr;          *jmp_delay_decode = d; // Copy current decode      } else          handle_pc(d); +    struct dtExecute e = execute(d); +    struct dtMemory m = memory(e); +    writeback(m); +      if (m.excause != EXCAUSE_NONE) {          if (jmp_delay_decode != nullptr)              dtDecodeInit(*jmp_delay_decode); @@ -575,8 +587,12 @@ void CorePipelined::do_step() {      // Now process program counter (loop connections from decode stage)      if (!stall) {          dt_f = fetch(); -        if (handle_pc(dt_d)) +        if (handle_pc(dt_d)) {              dt_f.in_delay_slot = true; +        } else { +            if (dt_d.nb_skip_ds) +                dtFetchInit(dt_f); +        }      } else {          // Run fetch stage on empty          fetch(); diff --git a/qtmips_machine/core.h b/qtmips_machine/core.h index fa0d368..8f3acec 100644 --- a/qtmips_machine/core.h +++ b/qtmips_machine/core.h @@ -177,6 +177,7 @@ protected:          bool jump;       // jump          bool bj_not;     // negate branch condition          bool bgt_blez;   // BGTZ/BLEZ instead of BGEZ/BLTZ +        bool nb_skip_ds; // Skip delay slot if branch is not taken          bool forward_m_d_rs; // forwarding required for beq, bne, blez, bgtz, jr nad jalr          bool forward_m_d_rt; // forwarding required for beq, bne          enum AluOp aluop; // Decoded ALU operation diff --git a/qtmips_machine/instruction.cpp b/qtmips_machine/instruction.cpp index d72dc7d..3fb8839 100644 --- a/qtmips_machine/instruction.cpp +++ b/qtmips_machine/instruction.cpp @@ -235,9 +235,9 @@ static const struct InstructionMap  regimm_instruction_map[] = {      {"BGEZ", IT_I, NOALU, NOMEM, nullptr,       // BGEZ       .flags = IMF_SUPPORTED | IMF_BJR_REQ_RS | IMF_BRANCH | IMF_BJ_NOT},      {"BLTZL", IT_I, NOALU, NOMEM, nullptr,       // BLTZL -     .flags = IMF_BJR_REQ_RS}, +     .flags = IMF_SUPPORTED | IMF_BJR_REQ_RS | IMF_BRANCH | IMF_NB_SKIP_DS},      {"BGEZL", IT_I, NOALU, NOMEM, nullptr,       // BGEZL -     .flags = IMF_BJR_REQ_RS | IMF_BJ_NOT}, +     .flags = IMF_SUPPORTED | IMF_BJR_REQ_RS | IMF_BRANCH | IMF_NB_SKIP_DS | IMF_BJ_NOT},      IM_UNKNOWN,      IM_UNKNOWN,      IM_UNKNOWN, @@ -256,14 +256,14 @@ static const struct InstructionMap  regimm_instruction_map[] = {      {"TNEI", IT_I, NOALU, NOMEM, nullptr,       // TNEI       .flags = IMF_BJR_REQ_RS},      IM_UNKNOWN, -    {"BLTZAL", IT_I, ALU_OP_PASS_T, NOMEM, nullptr,       // BLTZAL +    {"BLTZAL", IT_I, ALU_OP_PASS_T, NOMEM, nullptr, // BLTZAL       .flags = FLAGS_J_B_PC_TO_R31 | IMF_BJR_REQ_RS | IMF_BRANCH}, -    {"BGEZAL", IT_I, ALU_OP_PASS_T, NOMEM, nullptr,       // BGEZAL +    {"BGEZAL", IT_I, ALU_OP_PASS_T, NOMEM, nullptr, // BGEZAL       .flags = FLAGS_J_B_PC_TO_R31 | IMF_BJR_REQ_RS | IMF_BRANCH | IMF_BJ_NOT}, -    {"BLTZALL", IT_I, NOALU, NOMEM, nullptr,       // BLTZALL -     .flags = IMF_BJR_REQ_RS}, -    {"BGEZALL", IT_I, NOALU, NOMEM, nullptr,       // BGEZALL -     .flags = IMF_BJR_REQ_RS | IMF_BJ_NOT}, +    {"BLTZALL", IT_I, ALU_OP_PASS_T, NOMEM, nullptr, // BLTZALL +     .flags = FLAGS_J_B_PC_TO_R31 | IMF_BJR_REQ_RS | IMF_BRANCH | IMF_NB_SKIP_DS }, +    {"BGEZALL", IT_I, ALU_OP_PASS_T, NOMEM, nullptr, // BGEZALL +     .flags = FLAGS_J_B_PC_TO_R31 | IMF_BJR_REQ_RS | IMF_BRANCH | IMF_NB_SKIP_DS | IMF_BJ_NOT},      IM_UNKNOWN,      IM_UNKNOWN,      IM_UNKNOWN, @@ -319,10 +319,14 @@ static const struct InstructionMap instruction_map[] = {      IM_UNKNOWN,  // 17      IM_UNKNOWN,  // 18      IM_UNKNOWN,  // 19 -    IM_UNKNOWN,  // 20 -    IM_UNKNOWN,  // 21 -    IM_UNKNOWN,  // 22 -    IM_UNKNOWN,  // 23 +    {"BEQL",    IT_I, NOALU, NOMEM, nullptr,         // BEQL +     .flags = IMF_SUPPORTED | IMF_BJR_REQ_RS | IMF_BJR_REQ_RT | IMF_BRANCH | IMF_NB_SKIP_DS}, +    {"BNEL",    IT_I, NOALU, NOMEM, nullptr,         // BNEL +     .flags = IMF_SUPPORTED | IMF_BJR_REQ_RS | IMF_BJR_REQ_RT | IMF_BRANCH | IMF_NB_SKIP_DS | IMF_BJ_NOT}, +    {"BLEZL",   IT_I, NOALU, NOMEM, nullptr,         // BLEZL +     .flags = IMF_SUPPORTED | IMF_BJR_REQ_RS | IMF_BRANCH | IMF_NB_SKIP_DS | IMF_BGTZ_BLEZ}, +    {"BGTZL",   IT_I, NOALU, NOMEM, nullptr,         // BGTZL +     .flags = IMF_SUPPORTED | IMF_BJR_REQ_RS | IMF_BRANCH | IMF_NB_SKIP_DS | IMF_BGTZ_BLEZ | IMF_BJ_NOT},      IM_UNKNOWN,  // 24      IM_UNKNOWN,  // 25      IM_UNKNOWN,  // 26 diff --git a/qtmips_machine/instruction.h b/qtmips_machine/instruction.h index e896ace..d8b9d00 100644 --- a/qtmips_machine/instruction.h +++ b/qtmips_machine/instruction.h @@ -67,7 +67,8 @@ enum InstructionFlags {      IMF_JUMP       = 1L<<19,      IMF_BJ_NOT     = 1L<<20,      IMF_BGTZ_BLEZ  = 1L<<21, -    IMF_EXCEPTION  = 1L<<22, +    IMF_NB_SKIP_DS = 1L<<22, // Skip instruction in delay slot if branch not taken +    IMF_EXCEPTION  = 1L<<23,  };  class Instruction {  | 
