add an illegal instruction trap test
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 5 Jul 2020 20:54:58 +0000 (21:54 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 5 Jul 2020 20:54:58 +0000 (21:54 +0100)
src/soc/decoder/isa/caller.py
src/soc/fu/trap/test/test_pipe_caller.py

index 35f02bd57c35e956623e8df7a88e001591cc9e1f..fbbbb75fdb390bf4cd3877dd70900f93e6ebde35 100644 (file)
@@ -331,14 +331,14 @@ class ISACaller:
         self.decoder = decoder2.dec
         self.dec2 = decoder2
 
         self.decoder = decoder2.dec
         self.dec2 = decoder2
 
-    def TRAP(self, trap_addr=0x700):
+    def TRAP(self, trap_addr=0x700, trap_bit=PI.TRAP):
         print ("TRAP:", hex(trap_addr))
         # store CIA(+4?) in SRR0, set NIA to 0x700
         # store MSR in SRR1, set MSR to um errr something, have to check spec
         self.spr['SRR0'] = self.pc.CIA
         self.spr['SRR1'] = self.namespace['MSR']
         self.trap_nia = SelectableInt(trap_addr, 64)
         print ("TRAP:", hex(trap_addr))
         # store CIA(+4?) in SRR0, set NIA to 0x700
         # store MSR in SRR1, set MSR to um errr something, have to check spec
         self.spr['SRR0'] = self.pc.CIA
         self.spr['SRR1'] = self.namespace['MSR']
         self.trap_nia = SelectableInt(trap_addr, 64)
-        self.namespace['MSR'][63-PI.TRAP] = 1 # bit 45, "this is a trap"
+        self.namespace['MSR'][63-trap_bit] = 1
 
     def memassign(self, ea, sz, val):
         self.mem.memassign(ea, sz, val)
 
     def memassign(self, ea, sz, val):
         self.mem.memassign(ea, sz, val)
@@ -527,14 +527,22 @@ class ISACaller:
         # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
         asmop = yield from self.get_assembly_name()
         print  ("call", name, asmop)
         # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
         asmop = yield from self.get_assembly_name()
         print  ("call", name, asmop)
+        illegal = False
         if name not in ['mtcrf', 'mtocrf']:
         if name not in ['mtcrf', 'mtocrf']:
-            assert name == asmop, "name %s != %s" % (name, asmop)
+            illegal = name != asmop
+
+        if illegal:
+            self.TRAP(0x700, PI.ILLEG)
+            self.namespace['NIA'] = self.trap_nia
+            self.pc.update(self.namespace)
+            return
 
         info = self.instrs[name]
         yield from self.prep_namespace(info.form, info.op_fields)
 
         # preserve order of register names
 
         info = self.instrs[name]
         yield from self.prep_namespace(info.form, info.op_fields)
 
         # preserve order of register names
-        input_names = create_args(list(info.read_regs) + list(info.uninit_regs))
+        input_names = create_args(list(info.read_regs) +
+                                  list(info.uninit_regs))
         print(input_names)
 
         # main registers (RT, RA ...)
         print(input_names)
 
         # main registers (RT, RA ...)
index b27cd0b2583e62fe310939c4eec1c33a116c999b..251ce50edfed72e416a8ac8347228f99fbb0240a 100644 (file)
@@ -107,6 +107,13 @@ class TrapTestCase(FHDLTestCase):
             initial_regs[2] = 1
             self.run_tst_program(Program(lst), initial_regs)
 
             initial_regs[2] = 1
             self.run_tst_program(Program(lst), initial_regs)
 
+    def test_999_illegal(self):
+        # ok, um this is a bit of a cheat: use an instruction we know
+        # is not implemented by either ISACaller or the core
+        lst = ["tbegin."]
+        initial_regs = [0] * 32
+        self.run_tst_program(Program(lst), initial_regs)
+
     def test_ilang(self):
         pspec = TrapPipeSpec(id_wid=2)
         alu = TrapBasePipe(pspec)
     def test_ilang(self):
         pspec = TrapPipeSpec(id_wid=2)
         alu = TrapBasePipe(pspec)