Implement bctr and mtspr
authorMichael Nolan <mtnolan2640@gmail.com>
Wed, 6 May 2020 15:35:47 +0000 (11:35 -0400)
committerMichael Nolan <mtnolan2640@gmail.com>
Wed, 6 May 2020 15:39:15 +0000 (11:39 -0400)
src/soc/decoder/isa/caller.py
src/soc/decoder/isa/sprset.patch [new file with mode: 0644]
src/soc/decoder/isa/test_caller.py
src/soc/decoder/power_enums.py
src/soc/decoder/selectable_int.py

index 7f24dbe849e1cd309fa75146abf7b9ce2b9f9809..736f7bb59ced1c88aef02586f2a9535b33209323 100644 (file)
@@ -141,15 +141,23 @@ class SPR(dict):
 
     def __getitem__(self, key):
         # if key in special_sprs get the special spr, otherwise return key
+        if isinstance(key, SelectableInt):
+            key = key.value
         key = special_sprs.get(key, key)
         if key in self:
             return dict.__getitem__(self, key)
         else:
-            return SelectableInt(0, 256)
+            import pdb; pdb.set_trace()
+            return SelectableInt(0, 64)
 
     def __setitem__(self, key, value):
+        if isinstance(key, SelectableInt):
+            key = key.value
         key = special_sprs.get(key, key)
         dict.__setitem__(self, key, value)
+
+    def __call__(self, ridx):
+        return self[ridx]
         
         
 
@@ -182,6 +190,7 @@ class ISACaller:
 
         self.namespace = {'GPR': self.gpr,
                           'MEM': self.mem,
+                          'SPR': self.spr,
                           'memassign': self.memassign,
                           'NIA': self.pc.NIA,
                           'CIA': self.pc.CIA,
@@ -211,7 +220,10 @@ class ISACaller:
         # list, here.
         fields = self.decoder.sigforms[formname]
         for name in op_fields:
-            sig = getattr(fields, name)
+            if name == 'spr':
+                sig = getattr(fields, name.upper())
+            else:
+                sig = getattr(fields, name)
             val = yield sig
             self.namespace[name] = SelectableInt(val, sig.width)
 
diff --git a/src/soc/decoder/isa/sprset.patch b/src/soc/decoder/isa/sprset.patch
new file mode 100644 (file)
index 0000000..dcdaf55
--- /dev/null
@@ -0,0 +1,11 @@
+--- sprset.py.orig     2020-05-06 11:36:45.228253359 -0400
++++ sprset.py  2020-05-06 11:20:17.627640518 -0400
+@@ -18,7 +18,7 @@
+                 SPR[n] = RS
+             else:
+                 SPR[n] = RS[32:64]
+-        elif length(SPR(n)) == 64:
++        elif len(SPR(n)) == 64:
+             SPR[n] = RS
+         else:
+             SPR[n] = RS[32:64]
index e5c2448b6d9edab5d0367ca49dda37ee9768138b..5f029570435303cf6657fe5f128dea3d3ac98e75 100644 (file)
@@ -116,6 +116,20 @@ class DecoderTestCase(FHDLTestCase):
             sim = self.run_tst_program(program)
             self.assertEqual(sim.spr['LR'], SelectableInt(0x4, 64))
 
+    def test_branch_ctr(self):
+        lst = ["addi 1, 0, 0x10",    # target of jump
+               "mtspr 9, 1",         # mtctr 1
+               "bcctr 20, 0, 0",     # bctr
+               "addi 2, 0, 0x1",     # should never execute
+               "addi 1, 0, 0x1234"]  # target of ctr
+        with Program(lst) as program:
+            sim = self.run_tst_program(program)
+            self.assertEqual(sim.spr['CTR'], SelectableInt(0x10, 64))
+            self.assertEqual(sim.gpr(1), SelectableInt(0x1234, 64))
+            self.assertEqual(sim.gpr(2), SelectableInt(0, 64))
+
+
+
 
     @unittest.skip("broken")  # FIXME
     def test_mtcrf(self):
index 7b5ab9115223f6da784d920d0c39405e469e96b8..79805527b980a6e43d4ec34f98768bd1a6d7fd89 100644 (file)
@@ -2,6 +2,7 @@ from enum import Enum, unique
 import csv
 import os
 from os.path import dirname, join
+from collections import namedtuple
 
 def find_wiki_file(name):
     filedir = os.path.dirname(os.path.abspath(__file__))
@@ -220,5 +221,6 @@ class CryIn(Enum):
 # http://bugs.libre-riscv.org/show_bug.cgi?id=261
 
 spr_csv = get_csv("sprs.csv")
+spr_info = namedtuple('spr_info', 'SPR priv_mtspr priv_mfspr len')
 fields = [(row['SPR'], int(row['Idx'])) for row in spr_csv]
 SPR = Enum('SPR', fields)
index 239162f3e046bdbe04db279e63a69a28eb9568e2..a052beb47f5431f73d4fc3126469a64059b5f8bf 100644 (file)
@@ -292,6 +292,9 @@ class SelectableInt:
         return "SelectableInt(value=0x{:x}, bits={})".format(self.value,
                                                            self.bits)
 
+    def __len__(self):
+        return self.bits
+
 def onebit(bit):
     return SelectableInt(1 if bit else 0, 1)