aboutsummaryrefslogtreecommitdiff
path: root/riscv
diff options
context:
space:
mode:
authorYunsup Lee <yunsup@cs.berkeley.edu>2013-10-18 17:34:54 -0700
committerYunsup Lee <yunsup@cs.berkeley.edu>2013-10-18 17:34:54 -0700
commitcb6cfc5f3ad18280c6dce1f03ee4ff87e4677dad (patch)
tree2f2416b151713f95aaa0d24d7a5163330c3d0d90 /riscv
parent9543d241b320cb1c4982949aa6d012940c8f5377 (diff)
downloadspike-cb6cfc5f3ad18280c6dce1f03ee4ff87e4677dad.zip
spike-cb6cfc5f3ad18280c6dce1f03ee4ff87e4677dad.tar.gz
spike-cb6cfc5f3ad18280c6dce1f03ee4ff87e4677dad.tar.bz2
refactor disassembler, and add hwacha disassembler
Diffstat (limited to 'riscv')
-rw-r--r--riscv/disasm.cc123
-rw-r--r--riscv/disasm.h55
-rw-r--r--riscv/extension.h3
-rw-r--r--riscv/interactive.cc9
-rw-r--r--riscv/processor.cc30
-rw-r--r--riscv/processor.h11
-rw-r--r--riscv/riscv-dis.cc2
-rw-r--r--riscv/rocc.cc6
-rw-r--r--riscv/rocc.h1
-rw-r--r--riscv/sim.cc17
-rw-r--r--riscv/sim.h5
11 files changed, 123 insertions, 139 deletions
diff --git a/riscv/disasm.cc b/riscv/disasm.cc
index caf4ff4..436aea3 100644
--- a/riscv/disasm.cc
+++ b/riscv/disasm.cc
@@ -6,14 +6,6 @@
#include <cstdarg>
#include <sstream>
#include <stdlib.h>
-using namespace std;
-
-class arg_t
-{
- public:
- virtual string to_string(insn_t val) const = 0;
- virtual ~arg_t() {}
-};
static const char* xpr[] = {
"zero", "ra", "s0", "s1", "s2", "s3", "s4", "s5",
@@ -29,35 +21,21 @@ static const char* fpr[] = {
"fa6", "fa7", "ft0", "ft1", "ft2", "ft3", "ft4", "ft5"
};
-static const char* vxpr[] = {
- "vx0", "vx1", "vx2", "vx3", "vx4", "vx5", "vx6", "vx7",
- "vx8", "vx9", "vx10", "vx11", "vx12", "vx13", "vx14", "vx15",
- "vx16", "vx17", "vx18", "vx19", "vx20", "vx21", "vx22", "vx23",
- "vx24", "vx25", "vx26", "vx27", "vx28", "vx29", "vx30", "vx31"
-};
-
-static const char* vfpr[] = {
- "vf0", "vf1", "vf2", "vf3", "vf4", "vf5", "vf6", "vf7",
- "vf8", "vf9", "vf10", "vf11", "vf12", "vf13", "vf14", "vf15",
- "vf16", "vf17", "vf18", "vf19", "vf20", "vf21", "vf22", "vf23",
- "vf24", "vf25", "vf26", "vf27", "vf28", "vf29", "vf30", "vf31"
-};
-
struct : public arg_t {
- string to_string(insn_t insn) const {
- return ::to_string((int)insn.i_imm()) + '(' + xpr[insn.rs1()] + ')';
+ std::string to_string(insn_t insn) const {
+ return std::to_string((int)insn.i_imm()) + '(' + xpr[insn.rs1()] + ')';
}
} load_address;
struct : public arg_t {
- string to_string(insn_t insn) const {
- return ::to_string((int)insn.s_imm()) + '(' + xpr[insn.rs1()] + ')';
+ std::string to_string(insn_t insn) const {
+ return std::to_string((int)insn.s_imm()) + '(' + xpr[insn.rs1()] + ')';
}
} store_address;
struct : public arg_t {
- string to_string(insn_t insn) const {
- return string("0(") + xpr[insn.rs1()] + ')';
+ std::string to_string(insn_t insn) const {
+ return std::string("0(") + xpr[insn.rs1()] + ')';
}
} amo_address;
@@ -105,49 +83,13 @@ struct : public arg_t {
struct : public arg_t {
std::string to_string(insn_t insn) const {
- return vxpr[insn.rd()];
- }
-} vxrd;
-
-struct : public arg_t {
- std::string to_string(insn_t insn) const {
- return vxpr[insn.rs1()];
- }
-} vxrs1;
-
-struct : public arg_t {
- std::string to_string(insn_t insn) const {
- return vfpr[insn.rd()];
- }
-} vfrd;
-
-struct : public arg_t {
- std::string to_string(insn_t insn) const {
- return vfpr[insn.rs1()];
- }
-} vfrs1;
-
-struct : public arg_t {
- std::string to_string(insn_t insn) const {
- return ::to_string(insn.i_imm() & 0x3f);
- }
-} nxregs;
-
-struct : public arg_t {
- std::string to_string(insn_t insn) const {
- return ::to_string((insn.i_imm() >> 6) & 0x3f);
- }
-} nfregs;
-
-struct : public arg_t {
- std::string to_string(insn_t insn) const {
- return string("pcr") + xpr[insn.rs1()];
+ return std::string("pcr") + xpr[insn.rs1()];
}
} pcr;
struct : public arg_t {
std::string to_string(insn_t insn) const {
- return ::to_string((int)insn.i_imm());
+ return std::to_string((int)insn.i_imm());
}
} imm;
@@ -179,52 +121,13 @@ struct : public arg_t {
}
} jump_target;
-class disasm_insn_t
-{
- public:
- disasm_insn_t(const char* name, uint32_t match, uint32_t mask,
- const std::vector<const arg_t*>& args)
- : match(match), mask(mask), args(args), name(name) {}
-
- bool operator == (insn_t insn) const
- {
- return (insn.bits() & mask) == match;
- }
-
- std::string to_string(insn_t insn) const
- {
- std::stringstream s;
- int len;
- for (len = 0; name[len]; len++)
- s << (name[len] == '_' ? '.' : name[len]);
-
- if (args.size())
- {
- s << std::string(std::max(1, 8 - len), ' ');
- for (size_t i = 0; i < args.size()-1; i++)
- s << args[i]->to_string(insn) << ", ";
- s << args[args.size()-1]->to_string(insn);
- }
- return s.str();
- }
-
- uint32_t get_match() const { return match; }
- uint32_t get_mask() const { return mask; }
-
- private:
- uint32_t match;
- uint32_t mask;
- std::vector<const arg_t*> args;
- const char* name;
-};
-
-std::string disassembler::disassemble(insn_t insn)
+std::string disassembler_t::disassemble(insn_t insn)
{
const disasm_insn_t* disasm_insn = lookup(insn);
return disasm_insn ? disasm_insn->to_string(insn) : "unknown";
}
-disassembler::disassembler()
+disassembler_t::disassembler_t()
{
const uint32_t mask_rd = 0x1fUL << 7;
const uint32_t match_rd_ra = 1UL << 7;
@@ -463,7 +366,7 @@ disassembler::disassembler()
#undef DECLARE_INSN
}
-const disasm_insn_t* disassembler::lookup(insn_t insn)
+const disasm_insn_t* disassembler_t::lookup(insn_t insn)
{
size_t idx = insn.bits() % HASH_SIZE;
for (size_t j = 0; j < chain[idx].size(); j++)
@@ -478,7 +381,7 @@ const disasm_insn_t* disassembler::lookup(insn_t insn)
return NULL;
}
-void disassembler::add_insn(disasm_insn_t* insn)
+void disassembler_t::add_insn(disasm_insn_t* insn)
{
size_t idx = HASH_SIZE;
if (insn->get_mask() % HASH_SIZE == HASH_SIZE - 1)
@@ -486,7 +389,7 @@ void disassembler::add_insn(disasm_insn_t* insn)
chain[idx].push_back(insn);
}
-disassembler::~disassembler()
+disassembler_t::~disassembler_t()
{
for (size_t i = 0; i < HASH_SIZE+1; i++)
for (size_t j = 0; j < chain[i].size(); j++)
diff --git a/riscv/disasm.h b/riscv/disasm.h
index ee6d919..b5aa6de 100644
--- a/riscv/disasm.h
+++ b/riscv/disasm.h
@@ -5,20 +5,65 @@
#include "decode.h"
#include <string>
+#include <sstream>
#include <vector>
-struct disasm_insn_t;
+class arg_t
+{
+ public:
+ virtual std::string to_string(insn_t val) const = 0;
+ virtual ~arg_t() {}
+};
-class disassembler
+class disasm_insn_t
{
public:
- disassembler();
- ~disassembler();
+ disasm_insn_t(const char* name, uint32_t match, uint32_t mask,
+ const std::vector<const arg_t*>& args)
+ : match(match), mask(mask), args(args), name(name) {}
+
+ bool operator == (insn_t insn) const
+ {
+ return (insn.bits() & mask) == match;
+ }
+
+ std::string to_string(insn_t insn) const
+ {
+ std::stringstream s;
+ int len;
+ for (len = 0; name[len]; len++)
+ s << (name[len] == '_' ? '.' : name[len]);
+
+ if (args.size())
+ {
+ s << std::string(std::max(1, 8 - len), ' ');
+ for (size_t i = 0; i < args.size()-1; i++)
+ s << args[i]->to_string(insn) << ", ";
+ s << args[args.size()-1]->to_string(insn);
+ }
+ return s.str();
+ }
+
+ uint32_t get_match() const { return match; }
+ uint32_t get_mask() const { return mask; }
+
+ private:
+ uint32_t match;
+ uint32_t mask;
+ std::vector<const arg_t*> args;
+ const char* name;
+};
+
+class disassembler_t
+{
+ public:
+ disassembler_t();
+ ~disassembler_t();
std::string disassemble(insn_t insn);
+ void add_insn(disasm_insn_t* insn);
private:
static const int HASH_SIZE = 256;
std::vector<const disasm_insn_t*> chain[HASH_SIZE+1];
- void add_insn(disasm_insn_t* insn);
const disasm_insn_t* lookup(insn_t insn);
};
diff --git a/riscv/extension.h b/riscv/extension.h
index da42db9..cce8345 100644
--- a/riscv/extension.h
+++ b/riscv/extension.h
@@ -2,6 +2,7 @@
#define _RISCV_COPROCESSOR_H
#include "processor.h"
+#include "disasm.h"
#include <map>
#include <string>
#include <vector>
@@ -11,8 +12,10 @@ class extension_t
{
public:
virtual std::vector<insn_desc_t> get_instructions() = 0;
+ virtual std::vector<disasm_insn_t*> get_disasms() = 0;
virtual const char* name() = 0;
virtual void reset() {};
+ virtual void set_debug(bool value) {};
virtual ~extension_t();
void set_processor(processor_t* _p) { p = _p; }
diff --git a/riscv/interactive.cc b/riscv/interactive.cc
index a1b7dd0..ad38ace 100644
--- a/riscv/interactive.cc
+++ b/riscv/interactive.cc
@@ -56,7 +56,8 @@ void sim_t::interactive()
if (!(ss >> cmd))
{
- step(1, true);
+ set_procs_debug(true);
+ step(1);
continue;
}
@@ -101,8 +102,9 @@ void sim_t::interactive_run(const std::string& cmd, const std::vector<std::strin
{
size_t steps = args.size() ? atoll(args[0].c_str()) : -1;
ctrlc_pressed = false;
+ set_procs_debug(noisy);
for (size_t i = 0; i < steps && !ctrlc_pressed; i++)
- step(1, noisy);
+ step(1);
}
void sim_t::interactive_quit(const std::string& cmd, const std::vector<std::string>& args)
@@ -269,6 +271,7 @@ void sim_t::interactive_until(const std::string& cmd, const std::vector<std::str
}
catch (trap_t t) {}
- step(1, false);
+ set_procs_debug(false);
+ step(1);
}
}
diff --git a/riscv/processor.cc b/riscv/processor.cc
index 77a81b3..ac5c1f7 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -15,7 +15,7 @@
#include <stdexcept>
processor_t::processor_t(sim_t* _sim, mmu_t* _mmu, uint32_t _id)
- : sim(_sim), mmu(_mmu), ext(NULL), id(_id), opcode_bits(0)
+ : sim(_sim), mmu(_mmu), ext(NULL), id(_id), debug(false), opcode_bits(0)
{
reset(true);
mmu->set_processor(this);
@@ -59,6 +59,13 @@ void state_t::reset()
load_reservation = -1;
}
+void processor_t::set_debug(bool value)
+{
+ debug = value;
+ if (ext)
+ ext->set_debug(value);
+}
+
void processor_t::reset(bool value)
{
if (run == !value)
@@ -88,7 +95,7 @@ void processor_t::take_interrupt()
throw trap_t((1ULL << ((state.sr & SR_S64) ? 63 : 31)) + i);
}
-void processor_t::step(size_t n, bool noisy)
+void processor_t::step(size_t n)
{
if(!run)
return;
@@ -105,7 +112,7 @@ void processor_t::step(size_t n, bool noisy)
#define execute_insn(noisy) \
do { \
mmu_t::insn_fetch_t fetch = _mmu->load_insn(npc); \
- if(noisy) disasm(fetch.insn.insn, npc); \
+ if(noisy) disasm(fetch.insn.insn); \
npc = fetch.func(this, fetch.insn.insn, npc); \
} while(0)
@@ -117,7 +124,7 @@ void processor_t::step(size_t n, bool noisy)
#define execute_insn(noisy) \
do { \
mmu_t::insn_fetch_t fetch = _mmu->load_insn(npc); \
- if(noisy) disasm(fetch.insn.insn, npc); \
+ if(noisy) disasm(fetch.insn.insn); \
bool in_spvr = state.sr & SR_S; \
if (!in_spvr) fprintf(stderr, "\n0x%016" PRIx64 " (0x%08" PRIx32 ") ", npc, fetch.insn.insn.bits()); \
/*if (!in_spvr) fprintf(stderr, "\n0x%016" PRIx64 " (0x%08" PRIx32 ") %s ", npc, fetch.insn.insn.bits(), disasmblr.disassemble(fetch.insn.insn).c_str());*/ \
@@ -125,7 +132,7 @@ void processor_t::step(size_t n, bool noisy)
} while(0)
#endif
- if(noisy) for( ; i < n; i++) // print out instructions as we go
+ if(debug) for( ; i < n; i++) // print out instructions as we go
execute_insn(true);
else
{
@@ -145,7 +152,7 @@ void processor_t::step(size_t n, bool noisy)
}
catch(trap_t& t)
{
- take_trap(npc, t, noisy);
+ take_trap(npc, t);
}
state.cycle += i;
@@ -157,9 +164,9 @@ void processor_t::step(size_t n, bool noisy)
set_interrupt(IRQ_TIMER, true);
}
-void processor_t::take_trap(reg_t pc, trap_t& t, bool noisy)
+void processor_t::take_trap(reg_t pc, trap_t& t)
{
- if (noisy)
+ if (debug)
fprintf(stderr, "core %3d: exception %s, epc 0x%016" PRIx64 "\n",
id, t.name(), pc);
@@ -182,12 +189,11 @@ void processor_t::deliver_ipi()
set_pcr(PCR_CLR_IPI, 1);
}
-void processor_t::disasm(insn_t insn, reg_t pc)
+void processor_t::disasm(insn_t insn)
{
// the disassembler is stateless, so we share it
- static disassembler disasm;
fprintf(stderr, "core %3d: 0x%016" PRIx64 " (0x%08" PRIx32 ") %s\n",
- id, state.pc, insn.bits(), disasm.disassemble(insn).c_str());
+ id, state.pc, insn.bits(), disassembler.disassemble(insn).c_str());
}
reg_t processor_t::set_pcr(int which, reg_t val)
@@ -342,6 +348,8 @@ void processor_t::register_extension(extension_t* x)
{
for (auto insn : x->get_instructions())
register_insn(insn);
+ for (auto disasm_insn : x->get_disasms())
+ disassembler.add_insn(disasm_insn);
if (ext != NULL)
throw std::logic_error("only one extension may be registered");
ext = x;
diff --git a/riscv/processor.h b/riscv/processor.h
index 6b007f2..0256bd8 100644
--- a/riscv/processor.h
+++ b/riscv/processor.h
@@ -1,9 +1,9 @@
// See LICENSE for license details.
-
#ifndef _RISCV_PROCESSOR_H
#define _RISCV_PROCESSOR_H
#include "decode.h"
+#include "disasm.h"
#include <cstring>
#include "config.h"
#include <map>
@@ -59,8 +59,9 @@ public:
processor_t(sim_t* _sim, mmu_t* _mmu, uint32_t _id);
~processor_t();
+ void set_debug(bool value);
void reset(bool value);
- void step(size_t n, bool noisy); // run for n cycles
+ void step(size_t n); // run for n cycles
void deliver_ipi(); // register an interprocessor interrupt
bool running() { return run; }
reg_t set_pcr(int which, reg_t val);
@@ -80,16 +81,18 @@ private:
sim_t* sim;
mmu_t* mmu; // main memory is always accessed via the mmu
extension_t* ext;
+ disassembler_t disassembler;
state_t state;
uint32_t id;
bool run; // !reset
+ bool debug;
unsigned opcode_bits;
std::multimap<uint32_t, insn_desc_t> opcode_map;
void take_interrupt(); // take a trap if any interrupts are pending
- void take_trap(reg_t pc, trap_t& t, bool noisy); // take an exception
- void disasm(insn_t insn, reg_t pc); // disassemble and print an instruction
+ void take_trap(reg_t pc, trap_t& t); // take an exception
+ void disasm(insn_t insn); // disassemble and print an instruction
friend class sim_t;
friend class mmu_t;
diff --git a/riscv/riscv-dis.cc b/riscv/riscv-dis.cc
index 62d522e..fdeb69f 100644
--- a/riscv/riscv-dis.cc
+++ b/riscv/riscv-dis.cc
@@ -15,7 +15,7 @@ using namespace std;
int main()
{
string s;
- disassembler d;
+ disassembler_t d;
while (getline(cin, s))
{
diff --git a/riscv/rocc.cc b/riscv/rocc.cc
index b148319..7988c01 100644
--- a/riscv/rocc.cc
+++ b/riscv/rocc.cc
@@ -36,3 +36,9 @@ std::vector<insn_desc_t> rocc_t::get_instructions()
insns.push_back((insn_desc_t){0x7b, 0x7f, &::illegal_instruction, c3});
return insns;
}
+
+std::vector<disasm_insn_t*> rocc_t::get_disasms()
+{
+ std::vector<disasm_insn_t*> insns;
+ return insns;
+}
diff --git a/riscv/rocc.h b/riscv/rocc.h
index e4148ec..63d074d 100644
--- a/riscv/rocc.h
+++ b/riscv/rocc.h
@@ -29,6 +29,7 @@ class rocc_t : public extension_t
virtual reg_t custom2(rocc_insn_t insn, reg_t xs1, reg_t xs2);
virtual reg_t custom3(rocc_insn_t insn, reg_t xs1, reg_t xs2);
std::vector<insn_desc_t> get_instructions();
+ std::vector<disasm_insn_t*> get_disasms();
};
#endif
diff --git a/riscv/sim.cc b/riscv/sim.cc
index a4a1c17..4d61555 100644
--- a/riscv/sim.cc
+++ b/riscv/sim.cc
@@ -79,16 +79,16 @@ void sim_t::run()
if (debug || ctrlc_pressed)
interactive();
else
- step(INTERLEAVE, false);
+ step(INTERLEAVE);
}
}
-void sim_t::step(size_t n, bool noisy)
+void sim_t::step(size_t n)
{
for (size_t i = 0, steps = 0; i < n; i += steps)
{
steps = std::min(n - i, INTERLEAVE - current_step);
- procs[current_proc]->step(steps, noisy);
+ procs[current_proc]->step(steps);
current_step += steps;
if (current_step == INTERLEAVE)
@@ -117,3 +117,14 @@ void sim_t::stop()
while (htif->tick())
;
}
+
+void sim_t::set_debug(bool value)
+{
+ debug = value;
+}
+
+void sim_t::set_procs_debug(bool value)
+{
+ for (size_t i=0; i< procs.size(); i++)
+ procs[i]->set_debug(value);
+}
diff --git a/riscv/sim.h b/riscv/sim.h
index bcb7c1c..e827087 100644
--- a/riscv/sim.h
+++ b/riscv/sim.h
@@ -22,7 +22,8 @@ public:
void run();
bool running();
void stop();
- void set_debug(bool value) { debug = value; }
+ void set_debug(bool value);
+ void set_procs_debug(bool value);
// deliver an IPI to a specific processor
void send_ipi(reg_t who);
@@ -41,7 +42,7 @@ private:
mmu_t* debug_mmu; // debug port into main memory
std::vector<processor_t*> procs;
- void step(size_t n, bool noisy); // step through simulation
+ void step(size_t n); // step through simulation
static const size_t INTERLEAVE = 5000;
size_t current_step;
size_t current_proc;