diff options
Diffstat (limited to 'qtmips_machine/core.cpp')
-rw-r--r-- | qtmips_machine/core.cpp | 136 |
1 files changed, 23 insertions, 113 deletions
diff --git a/qtmips_machine/core.cpp b/qtmips_machine/core.cpp index 839def2..fd37d6b 100644 --- a/qtmips_machine/core.cpp +++ b/qtmips_machine/core.cpp @@ -39,98 +39,6 @@ using namespace machine; -#define DM_SUPPORTED (1L<<0) -#define DM_MEMWRITE (1L<<1) -#define DM_MEMREAD (1L<<2) -#define DM_ALUSRC (1L<<3) -#define DM_REGD (1L<<4) -#define DM_REGWRITE (1L<<5) -#define DM_ZERO_EXTEND (1L<<6) -#define DM_PC_TO_R31 (1L<<7) -#define DM_BJR_REQ_RS (1L<<8) -#define DM_BJR_REQ_RT (1L<<9) - -struct DecodeMap { - long flags; - enum AluOp alu; - enum MemoryAccess::AccessControl mem_ctl; -}; - -#define NOALU .alu = ALU_OP_SLL -#define NOMEM .mem_ctl = MemoryAccess::AC_NONE -#define NOPE { .flags = 0, NOALU, NOMEM } - -#define FLAGS_ALU_I (DM_SUPPORTED | DM_ALUSRC | DM_REGWRITE) -#define FLAGS_ALU_I_ZE (DM_SUPPORTED | DM_ALUSRC | DM_REGWRITE | DM_ZERO_EXTEND) - -// This is map from opcode to signals. -static const struct DecodeMap dmap[] = { - { .flags = DM_SUPPORTED | DM_REGD | DM_REGWRITE, NOALU, NOMEM }, // Alu operations (aluop is decoded from function explicitly) - { .flags = DM_SUPPORTED | DM_BJR_REQ_RS, NOALU, NOMEM }, // REGIMM (BLTZ, BGEZ) - { .flags = DM_SUPPORTED, NOALU, NOMEM }, // J - { .flags = DM_SUPPORTED | DM_PC_TO_R31 | DM_REGWRITE, .alu = ALU_OP_PASS_S, NOMEM }, // JAL - { .flags = DM_SUPPORTED | DM_BJR_REQ_RS | DM_BJR_REQ_RT, NOALU, NOMEM }, // BEQ - { .flags = DM_SUPPORTED | DM_BJR_REQ_RS | DM_BJR_REQ_RT, NOALU, NOMEM }, // BNE - { .flags = DM_SUPPORTED | DM_BJR_REQ_RS, NOALU, NOMEM }, // BLEZ - { .flags = DM_SUPPORTED | DM_BJR_REQ_RS, NOALU, NOMEM }, // BGTZ - { .flags = FLAGS_ALU_I, .alu = ALU_OP_ADD, NOMEM }, // ADDI - { .flags = FLAGS_ALU_I, .alu = ALU_OP_ADDU, NOMEM }, // ADDIU - { .flags = FLAGS_ALU_I, .alu = ALU_OP_SLT, NOMEM }, // SLTI - { .flags = FLAGS_ALU_I, .alu = ALU_OP_SLTU, NOMEM }, // SLTIU - { .flags = FLAGS_ALU_I_ZE, .alu = ALU_OP_AND, NOMEM }, // ANDI - { .flags = FLAGS_ALU_I_ZE, .alu = ALU_OP_OR, NOMEM }, // ORI - { .flags = FLAGS_ALU_I_ZE, .alu = ALU_OP_XOR, NOMEM }, // XORI - { .flags = FLAGS_ALU_I, .alu = ALU_OP_LUI, NOMEM}, // LUI - NOPE, // 16 - NOPE, // 17 - NOPE, // 18 - NOPE, // 19 - NOPE, // 20 - NOPE, // 21 - NOPE, // 22 - NOPE, // 23 - NOPE, // 24 - NOPE, // 25 - NOPE, // 26 - NOPE, // 27 - NOPE, // 28 - NOPE, // 29 - NOPE, // 30 - NOPE, // 31 - { .flags = DM_SUPPORTED | DM_ALUSRC | DM_REGWRITE | DM_MEMREAD, .alu = ALU_OP_ADDU, .mem_ctl = MemoryAccess::AC_BYTE }, // LB - { .flags = DM_SUPPORTED | DM_ALUSRC | DM_REGWRITE | DM_MEMREAD, .alu = ALU_OP_ADDU, .mem_ctl = MemoryAccess::AC_HALFWORD }, // LH - NOPE, // LWL - { .flags = DM_SUPPORTED | DM_ALUSRC | DM_REGWRITE | DM_MEMREAD, .alu = ALU_OP_ADDU, .mem_ctl = MemoryAccess::AC_WORD }, // LW - { .flags = DM_SUPPORTED | DM_ALUSRC | DM_REGWRITE | DM_MEMREAD, .alu = ALU_OP_ADDU, .mem_ctl = MemoryAccess::AC_BYTE_UNSIGNED }, // LBU - { .flags = DM_SUPPORTED | DM_ALUSRC | DM_REGWRITE | DM_MEMREAD, .alu = ALU_OP_ADDU, .mem_ctl = MemoryAccess::AC_HALFWORD_UNSIGNED }, // LHU - NOPE, // LWR - NOPE, // 39 - { .flags = DM_SUPPORTED | DM_ALUSRC | DM_MEMWRITE, .alu = ALU_OP_ADDU, .mem_ctl = MemoryAccess::AC_BYTE }, // SB - { .flags = DM_SUPPORTED | DM_ALUSRC | DM_MEMWRITE, .alu = ALU_OP_ADDU, .mem_ctl = MemoryAccess::AC_HALFWORD }, // SH - NOPE, // SWL - { .flags = DM_SUPPORTED | DM_ALUSRC | DM_MEMWRITE, .alu = ALU_OP_ADDU, .mem_ctl = MemoryAccess::AC_WORD }, // SW - NOPE, // 44 - NOPE, // 45 - NOPE, // SWR - { .flags = DM_SUPPORTED | DM_ALUSRC, .alu = ALU_OP_ADDU, .mem_ctl = MemoryAccess::AC_CACHE_OP }, // CACHE - NOPE, // 48 - NOPE, // 49 - NOPE, // 50 - NOPE, // 51 - NOPE, // 52 - NOPE, // 53 - NOPE, // 54 - NOPE, // 55 - NOPE, // 56 - NOPE, // 57 - NOPE, // 58 - NOPE, // 59 - NOPE, // 60 - NOPE, // 61 - NOPE, // 62 - NOPE // 63 -}; - Core::Core(Registers *regs, MemoryAccess *mem_program, MemoryAccess *mem_data) { cycle_c = 0; this->regs = regs; @@ -165,20 +73,22 @@ struct Core::dtFetch Core::fetch() { struct Core::dtDecode Core::decode(const struct dtFetch &dt) { uint8_t rwrite; emit instruction_decoded(dt.inst); - const struct DecodeMap &dec = dmap[dt.inst.opcode()]; + enum InstructionFlags flags = dt.inst.flags(); + enum AluOp alu_op = dt.inst.alu_op(); + enum AccessControl mem_ctl = dt.inst.mem_ctl(); - if (!(dec.flags & DM_SUPPORTED)) + if (!(flags & IMF_SUPPORTED)) throw QTMIPS_EXCEPTION(UnsupportedInstruction, "Instruction with following opcode is not supported", QString::number(dt.inst.opcode(), 16)); std::uint32_t val_rs = regs->read_gp(dt.inst.rs()); std::uint32_t val_rt = regs->read_gp(dt.inst.rt()); std::uint32_t immediate_val; - bool regwrite = dec.flags & DM_REGWRITE; - bool regd = dec.flags & DM_REGD; - bool regd31 = dec.flags & DM_PC_TO_R31; + bool regwrite = flags & IMF_REGWRITE; + bool regd = flags & IMF_REGD; + bool regd31 = flags & IMF_PC_TO_R31; // requires rs for beq, bne, blez, bgtz, jr nad jalr - bool bjr_req_rs = dec.flags & DM_BJR_REQ_RS; + bool bjr_req_rs = flags & IMF_BJR_REQ_RS; if (dt.inst.opcode() == 0) { switch (dt.inst.funct()) { case ALU_OP_BREAK: @@ -207,9 +117,9 @@ struct Core::dtDecode Core::decode(const struct dtFetch &dt) { } } // requires rt for beq, bne - bool bjr_req_rt = dec.flags & DM_BJR_REQ_RT; + bool bjr_req_rt = flags & IMF_BJR_REQ_RT; - if (dec.flags & DM_ZERO_EXTEND) + if (flags & IMF_ZERO_EXTEND) immediate_val = dt.inst.immediate(); else immediate_val = sign_extend(dt.inst.immediate()); @@ -218,12 +128,12 @@ struct Core::dtDecode Core::decode(const struct dtFetch &dt) { emit decode_reg1_value(val_rs); emit decode_reg2_value(val_rt); emit decode_immediate_value(immediate_val); - emit decode_regw_value((bool)(dec.flags & DM_REGWRITE)); - emit decode_memtoreg_value((bool)(dec.flags & DM_MEMREAD)); - emit decode_memwrite_value((bool)(dec.flags & DM_MEMWRITE)); - emit decode_memread_value((bool)(dec.flags & DM_MEMREAD)); - emit decode_alusrc_value((bool)(dec.flags & DM_ALUSRC)); - emit decode_regdest_value((bool)(dec.flags & DM_REGD)); + emit decode_regw_value((bool)(flags & IMF_REGWRITE)); + emit decode_memtoreg_value((bool)(flags & IMF_MEMREAD)); + emit decode_memwrite_value((bool)(flags & IMF_MEMWRITE)); + emit decode_memread_value((bool)(flags & IMF_MEMREAD)); + emit decode_alusrc_value((bool)(flags & IMF_ALUSRC)); + emit decode_regdest_value((bool)(flags & IMF_REGD)); emit decode_rs_num_value(dt.inst.rs()); emit decode_rt_num_value(dt.inst.rt()); emit decode_rd_num_value(dt.inst.rd()); @@ -237,9 +147,9 @@ struct Core::dtDecode Core::decode(const struct dtFetch &dt) { return { .inst = dt.inst, - .memread = dec.flags & DM_MEMREAD, - .memwrite = dec.flags & DM_MEMWRITE, - .alusrc = dec.flags & DM_ALUSRC, + .memread = flags & IMF_MEMREAD, + .memwrite = flags & IMF_MEMWRITE, + .alusrc = flags & IMF_ALUSRC, .regd = regd, .regd31 = regd31, .regwrite = regwrite, @@ -247,8 +157,8 @@ struct Core::dtDecode Core::decode(const struct dtFetch &dt) { .bjr_req_rt = bjr_req_rt, .forward_m_d_rs = false, .forward_m_d_rt = false, - .aluop = dt.inst.opcode() == 0 ? (enum AluOp)dt.inst.funct() : dec.alu, - .memctl = dec.mem_ctl, + .aluop = dt.inst.opcode() == 0 ? (enum AluOp)dt.inst.funct() : alu_op, + .memctl = mem_ctl, .val_rs = val_rs, .val_rt = val_rt, .immediate_val = immediate_val, @@ -302,7 +212,7 @@ struct Core::dtMemory Core::memory(const struct dtExecute &dt) { emit instruction_memory(dt.inst); std::uint32_t towrite_val = dt.alu_val; - if (dt.memctl == MemoryAccess::AC_CACHE_OP) + if (dt.memctl == AC_CACHE_OP) mem_data->sync(); else if (dt.memwrite) mem_data->write_ctl(dt.memctl, dt.alu_val, dt.val_rt); @@ -423,7 +333,7 @@ void Core::dtExecuteInit(struct dtExecute &dt) { dt.memread = false; dt.memwrite = false; dt.regwrite = false; - dt.memctl = MemoryAccess::AC_NONE; + dt.memctl = AC_NONE; dt.val_rt = 0; dt.rwrite = 0; dt.alu_val = 0; |