Implement bctr and mtspr
[soc.git] / src / soc / decoder / isa / caller.py
index 03503330a3b2a50e9a35aad27c038be4d84195ad..736f7bb59ced1c88aef02586f2a9535b33209323 100644 (file)
@@ -9,6 +9,13 @@ instruction_info = namedtuple('instruction_info',
                               'func read_regs uninit_regs write_regs ' + \
                               'special_regs op_fields form asmregs')
 
+special_sprs = {
+    'LR': 8,
+    'CTR': 9,
+    'TAR': 815,
+    'XER': 0,
+    'VRSAVE': 256}
+
 
 def create_args(reglist, extra=None):
     args = OrderedSet()
@@ -127,6 +134,33 @@ class PC:
         namespace['NIA'] = self.NIA
 
 
+class SPR(dict):
+    def __init__(self, dec2):
+        self.sd = dec2
+        dict.__init__(self)
+
+    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:
+            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]
+        
+        
+
 class ISACaller:
     # decoder2 - an instance of power_decoder2
     # regfile - a list of initial values for the registers
@@ -134,8 +168,8 @@ class ISACaller:
         self.gpr = GPR(decoder2, regfile)
         self.mem = Mem()
         self.pc = PC()
+        self.spr = SPR(decoder2)
         # TODO, needed here:
-        # 4.4.4 III p971 SPR (same as GPR except for SPRs - best done as a dict
         # FPR (same as GPR except for FP nums)
         # 4.2.2 p124 FPSCR (definitely "separate" - not in SPR)
         #            note that mffs, mcrfs, mtfsf "manage" this FPSCR
@@ -156,12 +190,13 @@ class ISACaller:
 
         self.namespace = {'GPR': self.gpr,
                           'MEM': self.mem,
+                          'SPR': self.spr,
                           'memassign': self.memassign,
                           'NIA': self.pc.NIA,
                           'CIA': self.pc.CIA,
                           'CR': self.cr,
-                          'LR': self.undefined,
                           'undefined': self.undefined,
+                          'mode_is_64bit': True,
                           }
 
         # field-selectable versions of Condition Register TODO check bitranges?
@@ -185,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)
 
@@ -210,7 +248,10 @@ class ISACaller:
 
         # "special" registers
         for special in info.special_regs:
-            inputs.append(self.namespace[special])
+            if special in special_sprs:
+                inputs.append(self.spr[special])
+            else:
+                inputs.append(self.namespace[special])
 
         print(inputs)
         results = info.func(self, *inputs)
@@ -222,7 +263,10 @@ class ISACaller:
             for name, output in zip(output_names, results):
                 if name in info.special_regs:
                     print('writing special %s' % name, output)
-                    self.namespace[name].eq(output)
+                    if name in special_sprs:
+                        self.spr[name] = output
+                    else:
+                        self.namespace[name].eq(output)
                 else:
                     regnum = yield getattr(self.decoder, name)
                     print('writing reg %d' % regnum)