redirect instructions through a class called sv_proc_t
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 11 Oct 2018 20:45:26 +0000 (21:45 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 11 Oct 2018 20:45:26 +0000 (21:45 +0100)
preparing the groundwork for a total over-ride of macros such as
WRITE_RD, and so on, so that element width can be implemented

id_regs.py
riscv/insn_template_sv.cc
riscv/processor.cc
riscv/processor.h
riscv/riscv.mk.in
riscv/sv_insn_redirect.cc [new file with mode: 0644]
riscv/sv_insn_redirect.h [new file with mode: 0644]
sv_proc_gen.py [new file with mode: 0644]

index e7a434bd1fd49a9971b97007140f2940c53e09af..614eeac758b17a0afb3cdb2fd70a7ce2f69e10a4 100644 (file)
@@ -169,6 +169,10 @@ def find_registers(fname, insn, twin_predication, immed_offset, is_branch):
 
     return '\n'.join(res)
 
+sv_hdr_template = """\
+    reg_t sv_proc_t::%s(processor_t* p, insn_t s_insn, reg_t pc);
+"""
+
 if __name__ == '__main__':
     files = list_insns()
     for (fname, insn) in files:
@@ -219,3 +223,4 @@ if __name__ == '__main__':
             txt += find_registers(fname, insn, twin_predication,
                                   immed_offset, is_branch)
             f.write(txt)
+
index f5796462222169df321dfa52bb5d0739d88c6c35..f815e07dd814612623f31f9f33a3d49a51efdeeb 100644 (file)
@@ -60,6 +60,7 @@
 #define str(s) #s
 
 #include "sv.h"
+#include "sv_insn_redirect.h"
 
 #ifdef INSN_TYPE_BRANCH
     #define set_pc(x) insn.setpc(xlen, vlen, npc, x, *dest_offs, target_reg);
 #endif
 
 reg_t FN(processor_t* p, insn_t s_insn, reg_t pc)
+{
+    return p->s.FN(p, s_insn, pc);
+}
+
+reg_t sv_proc_t::FN(processor_t* p, insn_t s_insn, reg_t pc)
 {
   int xlen = ISASZ;
   reg_t npc = sext_xlen(pc + insn_length(INSNCODE));
index c6c8457ea121f494131df08cd2d349d2d4d7557d..68128d2ea9feaf6adff4dbaebcc7e8017f67b8d5 100644 (file)
@@ -15,6 +15,9 @@
 #include <limits.h>
 #include <stdexcept>
 #include <algorithm>
+#ifdef SPIKE_SIMPLEV
+#include "sv_insn_redirect.h"
+#endif
 
 #undef STATE
 #define STATE state
@@ -23,6 +26,9 @@ processor_t::processor_t(const char* isa, simif_t* sim, uint32_t id,
         bool halt_on_reset)
   : debug(false), halt_request(false), sim(sim), ext(NULL), id(id),
   halt_on_reset(halt_on_reset), last_pc(1), executions(1)
+#ifdef SPIKE_SIMPLEV
+    , s()
+#endif
 {
   parse_isa_string(isa);
   register_base_instructions();
index fe06ec4d3999bb23d84b5e67d2e7cf46f80fd1b6..80d33b6284b710151f164ca4f55775c0e8391d85 100644 (file)
@@ -12,6 +12,7 @@
 #include "debug_rom_defines.h"
 #ifdef SPIKE_SIMPLEV
 #include "sv_decode.h"
+#include "sv_insn_redirect.h"
 #endif
 
 class processor_t;
@@ -349,6 +350,11 @@ private:
 
   // Track repeated executions for processor_t::disasm()
   uint64_t last_pc, last_bits, executions;
+
+#ifdef SPIKE_SIMPLEV
+public:
+    sv_proc_t s;
+#endif
 };
 
 reg_t illegal_instruction(processor_t* p, insn_t insn, reg_t pc);
index 045d58ab88e620b7f2c8e695c6d9e03e5591e26f..9226eff2ef0a939e396073c9a7c79b2aa1aea001 100644 (file)
@@ -24,6 +24,9 @@ riscv_hdrs = \
        extension.h \
        rocc.h \
        insn_template.h \
+       sv.h \
+       sv_decode.h \
+       sv_insn_redirect.h \
        mulhi.h \
        debug_module.h \
        debug_rom_defines.h \
@@ -53,6 +56,7 @@ riscv_srcs = \
        debug_module.cc \
        remote_bitbang.cc \
        sv.cc \
+       sv_insn_redirect.cc \
        jtag_dtm.cc \
        $(riscv_gen_srcs) \
 
@@ -306,6 +310,7 @@ insn_list.h: $(src_dir)/riscv/riscv.mk.in
                printf 'DEFINE_INSN(%s)\n' "$${insn}" ; \
        done > $@.tmp
        mv $@.tmp $@
+       python sv_proc_gen.py
 
 $(riscv_gen_srcs): %.cc: insns/%.h insn_template.cc
        sed 's/NAME/$(subst .cc,,$@)/' $(src_dir)/riscv/insn_template.cc | sed 's/OPCODE/$(call get_opcode,$(src_dir)/riscv/encoding.h,$(subst .cc,,$@))/' > $@
diff --git a/riscv/sv_insn_redirect.cc b/riscv/sv_insn_redirect.cc
new file mode 100644 (file)
index 0000000..805ce74
--- /dev/null
@@ -0,0 +1,8 @@
+#include "sv_insn_redirect.h"
+
+/*
+void (WRITE_RD)(reg_t value)
+{
+    WRITE_RD( value );
+}
+*/
diff --git a/riscv/sv_insn_redirect.h b/riscv/sv_insn_redirect.h
new file mode 100644 (file)
index 0000000..bc2514e
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef SV_INSN_REDIRECT_H
+#define SV_INSN_REDIRECT_H
+
+#include "decode.h"
+
+//extern void (WRITE_RD)(reg_t value);
+
+class processor_t;
+
+class sv_proc_t
+{
+public:
+    sv_proc_t() {}
+#include "sv_insn_decl.h"
+};
+
+#endif
diff --git a/sv_proc_gen.py b/sv_proc_gen.py
new file mode 100644 (file)
index 0000000..13eddaf
--- /dev/null
@@ -0,0 +1,52 @@
+#!/usr/bin/env python
+# Copyright (C) 2018 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
+
+""" identify registers used in riscv/insns/*.h and create code
+    that can be used in spike at runtime
+
+    the design of spike assumes that once an opcode is identified,
+    the role of decoding the instruction is implicitly rolled into
+    and included inside the function that emulates that opcode.
+
+    however there may be circumstances where the behaviour of an
+    instruction has to change depending on "tags" associated with
+    the registers (security extensions, simple-v extension).
+
+    therefore this code walks the instruction implementations
+    in riscv/insns/*.h looking for register usage patterns.
+    the resultant table can be used *prior* to the emulation,
+    without having to manually maintain such a table.
+"""
+
+import os
+import sys
+
+insns_dir = "./riscv/insns"
+def list_insns():
+    if len(sys.argv) == 2:
+        fullfname = sys.argv[1]
+        pth, fname = os.path.split(fullfname)
+        insn = fname[:-2]
+        return [(fullfname, insn)]
+
+    res = []
+    for fname in os.listdir(insns_dir):
+        if not fname.endswith(".h"):
+            continue
+        if fname.startswith("regs_"):
+            continue
+        insn = fname[:-2]
+        res.append((os.path.join(insns_dir, fname), insn))
+    return res
+
+sv_hdr_template = """\
+    reg_t (rv32_{0}) (processor_t* p, insn_t s_insn, reg_t pc);
+    reg_t (rv64_{0}) (processor_t* p, insn_t s_insn, reg_t pc);
+"""
+
+if __name__ == '__main__':
+    files = list_insns()
+    with open("riscv/sv_insn_decl.h", "w") as f:
+        for (fname, insn) in files:
+            f.write(sv_hdr_template.format(insn))
+