From 08d7e3dabd81e9d6e4f73aa5889a1d709242177c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= Date: Wed, 3 Jan 2018 17:52:45 +0100 Subject: Allow delay slot disable for non-pipelined core --- qtmips_machine/core.cpp | 20 ++++++++++++++++---- qtmips_machine/core.h | 5 +++-- qtmips_machine/machineconfig.cpp | 16 ++++++++-------- qtmips_machine/machineconfig.h | 8 ++++---- qtmips_machine/qtmipsmachine.cpp | 2 +- qtmips_machine/tests/testcore.cpp | 6 +++--- 6 files changed, 35 insertions(+), 22 deletions(-) diff --git a/qtmips_machine/core.cpp b/qtmips_machine/core.cpp index 276931c..53b7cad 100644 --- a/qtmips_machine/core.cpp +++ b/qtmips_machine/core.cpp @@ -257,9 +257,18 @@ void Core::dtMemoryInit(struct dtMemory &dt) { dt.towrite_val = 0; } -CoreSingle::CoreSingle(Registers *regs, MemoryAccess *mem) : \ +CoreSingle::CoreSingle(Registers *regs, MemoryAccess *mem, bool jmp_delay_slot) : \ Core(regs, mem) { - dtDecodeInit(jmp_delay_decode); + if (jmp_delay_slot) { + jmp_delay_decode = new struct Core::dtDecode(); + dtDecodeInit(*jmp_delay_decode); + } else + jmp_delay_decode = nullptr; +} + +CoreSingle::~CoreSingle() { + if (jmp_delay_decode != nullptr) + delete jmp_delay_decode; } void CoreSingle::step() { @@ -268,8 +277,11 @@ void CoreSingle::step() { struct dtExecute e = execute(d); struct dtMemory m = memory(e); writeback(m); - handle_pc(jmp_delay_decode); - jmp_delay_decode = d; // Copy current decode + if (jmp_delay_decode != nullptr) { + handle_pc(*jmp_delay_decode); + *jmp_delay_decode = d; // Copy current decode + } else + handle_pc(d); } CorePipelined::CorePipelined(Registers *regs, MemoryAccess *mem) : \ diff --git a/qtmips_machine/core.h b/qtmips_machine/core.h index b09e297..7d38d79 100644 --- a/qtmips_machine/core.h +++ b/qtmips_machine/core.h @@ -70,12 +70,13 @@ protected: class CoreSingle : public Core { public: - CoreSingle(Registers *regs, MemoryAccess *mem); + CoreSingle(Registers *regs, MemoryAccess *mem, bool jmp_delay_slot); + ~CoreSingle(); void step(); private: - struct Core::dtDecode jmp_delay_decode; + struct Core::dtDecode *jmp_delay_decode; }; class CorePipelined : public Core { diff --git a/qtmips_machine/machineconfig.cpp b/qtmips_machine/machineconfig.cpp index 2b4da34..0947e22 100644 --- a/qtmips_machine/machineconfig.cpp +++ b/qtmips_machine/machineconfig.cpp @@ -4,14 +4,14 @@ using namespace machine; MachineConfig::MachineConfig() { pipeline = false; - jumppred = false; + delayslot = true; cache_type = CCT_NONE; elf_path = QString(""); } MachineConfig::MachineConfig(MachineConfig *cc) { pipeline = cc->pipelined(); - jumppred = cc->jump_prediction(); + delayslot = cc->delay_slot(); cache_type = cc->cache(); elf_path = cc->elf(); } @@ -20,10 +20,10 @@ void MachineConfig::set_pipelined(bool v) { pipeline = v; } -void MachineConfig::set_jump_prediction(bool v) { - jumppred = v; - if (jumppred) - pipeline = true; +void MachineConfig::set_delay_slot(bool v) { + delayslot = v; + if (!delayslot) + pipeline = false; } void MachineConfig::set_cache(enum CacheType cc) { @@ -38,8 +38,8 @@ bool MachineConfig::pipelined() const { return pipeline; } -bool MachineConfig::jump_prediction() const { - return jumppred; +bool MachineConfig::delay_slot() const { + return delayslot; } enum MachineConfig::CacheType MachineConfig::cache() const { diff --git a/qtmips_machine/machineconfig.h b/qtmips_machine/machineconfig.h index 8e58d12..d872686 100644 --- a/qtmips_machine/machineconfig.h +++ b/qtmips_machine/machineconfig.h @@ -20,8 +20,8 @@ public: // In default disabled. void set_pipelined(bool); // Configure if we want to do jump prediction - // In default disabled. When enabled it also automatically enables pipelining - void set_jump_prediction(bool); + // In default enabled. When disabled it also automatically disables pipelining. + void set_delay_slot(bool); // Configure cache type // In default CCT_NONE is used. void set_cache(enum CacheType); @@ -29,12 +29,12 @@ public: void set_elf(QString path); bool pipelined() const; - bool jump_prediction() const; + bool delay_slot() const; enum CacheType cache() const; QString elf() const; private: - bool pipeline, jumppred; + bool pipeline, delayslot; enum CacheType cache_type; QString elf_path; }; diff --git a/qtmips_machine/qtmipsmachine.cpp b/qtmips_machine/qtmipsmachine.cpp index 6593dd0..3d79c7c 100644 --- a/qtmips_machine/qtmipsmachine.cpp +++ b/qtmips_machine/qtmipsmachine.cpp @@ -33,7 +33,7 @@ QtMipsMachine::QtMipsMachine(const MachineConfig &cc) { if (cc.pipelined()) cr = new CorePipelined(regs, coremem); else - cr = new CoreSingle(regs, coremem); + cr = new CoreSingle(regs, coremem, cc.delay_slot()); run_speed = 1; run_t = new QTimer(this); diff --git a/qtmips_machine/tests/testcore.cpp b/qtmips_machine/tests/testcore.cpp index 0bd18ba..1e5b502 100644 --- a/qtmips_machine/tests/testcore.cpp +++ b/qtmips_machine/tests/testcore.cpp @@ -186,7 +186,7 @@ void MachineTests::singlecore_regs() { mem.write_word(res.read_pc(), i.data()); // Store single instruction (anything else should be 0 so NOP effectively) Memory mem_used(mem); // Create memory copy - CoreSingle core(&init, &mem_used); + CoreSingle core(&init, &mem_used, true); core.step(); // Single step should be enought as this is risc without pipeline res.pc_inc(); // We did single step so increment program counter accordingly @@ -272,7 +272,7 @@ void MachineTests::singlecore_jmp() { Memory mem_used(mem); Registers regs_used(regs); - CoreSingle core(®s_used, &mem_used); + CoreSingle core(®s_used, &mem_used, true); core.step(); QCOMPARE(regs.read_pc() + 4, regs_used.read_pc()); // First execute delay slot core.step(); @@ -397,7 +397,7 @@ void MachineTests::singlecore_mem() { mem_init.write_word(regs_init.read_pc(), i.data()); mem_res.write_word(regs_init.read_pc(), i.data()); - CoreSingle core(®s_init, &mem_init); + CoreSingle core(®s_init, &mem_init, true); core.step(); regs_res.pc_inc(); -- cgit v1.2.3