aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--qtmips_machine/alu.cpp4
-rw-r--r--qtmips_machine/core.cpp30
-rw-r--r--qtmips_machine/core.h7
-rw-r--r--qtmips_machine/instruction.cpp6
-rw-r--r--qtmips_machine/machinedefs.h1
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)
};