diff options
-rw-r--r-- | qtmips_machine/alu.cpp | 4 | ||||
-rw-r--r-- | qtmips_machine/core.cpp | 30 | ||||
-rw-r--r-- | qtmips_machine/core.h | 7 | ||||
-rw-r--r-- | qtmips_machine/instruction.cpp | 6 | ||||
-rw-r--r-- | qtmips_machine/machinedefs.h | 1 |
5 files changed, 41 insertions, 7 deletions
diff --git a/qtmips_machine/alu.cpp b/qtmips_machine/alu.cpp index 2ac27a5..ad0e3c9 100644 --- a/qtmips_machine/alu.cpp +++ b/qtmips_machine/alu.cpp @@ -134,7 +134,9 @@ std::uint32_t machine::alu_operate(enum AluOp operation, std::uint32_t s, std::u return t; case ALU_OP_BREAK: return 0; - case ALU_OP_SYSCALL: // Pass s argument without change for JAL + case ALU_OP_SYSCALL: + return 0; + case ALU_OP_RDHWR: return 0; default: throw QTMIPS_EXCEPTION(UnsupportedAluOperation, "Unknown ALU operation", QString::number(operation, 16)); diff --git a/qtmips_machine/core.cpp b/qtmips_machine/core.cpp index 20353be..35f64af 100644 --- a/qtmips_machine/core.cpp +++ b/qtmips_machine/core.cpp @@ -39,13 +39,15 @@ using namespace machine; -Core::Core(Registers *regs, MemoryAccess *mem_program, MemoryAccess *mem_data) : - ex_handlers() { +Core::Core(Registers *regs, MemoryAccess *mem_program, MemoryAccess *mem_data, + unsigned int min_cache_row_size) : ex_handlers() { cycle_c = 0; this->regs = regs; this->mem_program = mem_program; this->mem_data = mem_data; - ex_default_handler = new StopExceptionHandler(); + this->ex_default_handler = new StopExceptionHandler(); + this->min_cache_row_size = min_cache_row_size; + this->hwr_user_local = 0xe0000000; } void Core::step() { @@ -221,6 +223,28 @@ struct Core::dtExecute Core::execute(const struct dtDecode &dt) { if (discard) regwrite = false; + if (dt.aluop == ALU_OP_RDHWR) { + switch (dt.inst.rd()) { + case 0: // CPUNum + alu_val = 0; + break; + case 1: // SYNCI_Step + alu_val = min_cache_row_size; + break; + case 2: // CC + alu_val = cycle_c; + break; + case 3: // CCRes + alu_val = 1; + break; + case 29: // UserLocal + alu_val = hwr_user_local; + break; + default: + alu_val = 0; + } + } + emit execute_alu_value(alu_val); emit execute_reg1_value(dt.val_rs); emit execute_reg2_value(dt.val_rt); diff --git a/qtmips_machine/core.h b/qtmips_machine/core.h index 8f3acec..3303438 100644 --- a/qtmips_machine/core.h +++ b/qtmips_machine/core.h @@ -69,7 +69,8 @@ public: class Core : public QObject { Q_OBJECT public: - Core(Registers *regs, MemoryAccess *mem_program, MemoryAccess *mem_data); + Core(Registers *regs, MemoryAccess *mem_program, MemoryAccess *mem_data, + unsigned int min_cache_row_size = 1); void step(); // Do single step void reset(); // Reset core (only core, memory and registers has to be reseted separately) @@ -230,7 +231,9 @@ protected: void dtMemoryInit(struct dtMemory &dt); private: - unsigned cycle_c; + unsigned int cycle_c; + unsigned int min_cache_row_size; + std::uint32_t hwr_user_local; }; class CoreSingle : public Core { diff --git a/qtmips_machine/instruction.cpp b/qtmips_machine/instruction.cpp index 030b79f..70247bd 100644 --- a/qtmips_machine/instruction.cpp +++ b/qtmips_machine/instruction.cpp @@ -223,7 +223,7 @@ static const struct InstructionMap special3_instruction_map[] = { IM_UNKNOWN, // 57 IM_UNKNOWN, // 58 {"RDHWR", IT_R, ALU_OP_NOP, NOMEM, nullptr, - .flags = FLAGS_ALU_T_R_TD}, + .flags = IMF_SUPPORTED | IMF_REGWRITE}, IM_UNKNOWN, // 60 IM_UNKNOWN, // 61 IM_UNKNOWN, // 62 @@ -606,6 +606,10 @@ QString Instruction::to_str(std::int32_t inst_addr) const { next_delim = ", "; } } + if ((im.flags & IMF_REGWRITE) && !(im.flags & IMF_REGD)) { + res += next_delim + "$" + QString::number(rd()); + next_delim = ", "; + } break; } case T_UNKNOWN: diff --git a/qtmips_machine/machinedefs.h b/qtmips_machine/machinedefs.h index 5e8acd6..05bf103 100644 --- a/qtmips_machine/machinedefs.h +++ b/qtmips_machine/machinedefs.h @@ -91,6 +91,7 @@ enum AluOp : std::uint8_t { ALU_OP_PASS_T, // Pass t argument without change for JAL ALU_OP_BREAK, ALU_OP_SYSCALL, + ALU_OP_RDHWR, ALU_OP_UNKNOWN, ALU_OP_LAST // First impossible operation (just to be sure that we don't overflow) }; |