add in special regs to be passed out of function (as return results)
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 7 Apr 2020 16:49:46 +0000 (17:49 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 7 Apr 2020 16:49:46 +0000 (17:49 +0100)
src/soc/decoder/isa/caller.py
src/soc/decoder/isa/test_caller.py
src/soc/decoder/pseudo/parser.py
src/soc/decoder/pseudo/pywriter.py
src/soc/decoder/selectable_int.py

index 050e1c85c2cb45d44cd2c0a9bb870de71351e527..e3c2ec0564b7bece48481a48d72f1f11b285485f 100644 (file)
@@ -189,10 +189,11 @@ class ISACaller:
         info = self.instrs[name]
         yield from self.prep_namespace(info.form, info.op_fields)
 
-        input_names = create_args(info.read_regs | info.uninit_regs |
-                                  info.special_regs)
+        # preserve order of register names
+        input_names = create_args(list(info.read_regs) + list(info.uninit_regs))
         print(input_names)
 
+        # main registers (RT, RA ...)
         inputs = []
         for name in input_names:
             regnum = yield getattr(self.decoder, name)
@@ -200,18 +201,30 @@ class ISACaller:
             self.namespace[regname] = regnum
             print('reading reg %d' % regnum)
             inputs.append(self.gpr(regnum))
+
+        # "special" registers
+        for special in info.special_regs:
+            inputs.append(self.namespace[special])
+
         print(inputs)
         results = info.func(self, *inputs)
         print(results)
 
+        # any modified return results?
         if info.write_regs:
             output_names = create_args(info.write_regs)
             for name, output in zip(output_names, results):
-                regnum = yield getattr(self.decoder, name)
-                print('writing reg %d' % regnum)
-                if output.bits > 64:
-                    output = SelectableInt(output.value, 64)
-                self.gpr[regnum] = output
+                if name in info.special_regs:
+                    print('writing special %s' % name, output)
+                    self.namespace[name].eq(output)
+                else:
+                    regnum = yield getattr(self.decoder, name)
+                    print('writing reg %d' % regnum)
+                    if output.bits > 64:
+                        output = SelectableInt(output.value, 64)
+                    self.gpr[regnum] = output
+
+        # update program counter
         self.pc.update(self.namespace)
 
 
index 2d2f5bdcc78977ce74f10f08285576652307443d..558172bb61cf54664a99360969abec82075c7d1e 100644 (file)
@@ -96,7 +96,9 @@ class DecoderTestCase(FHDLTestCase):
         with Program(lst) as program:
             sim = self.run_tst_program(program)
         print ("cr", sim.cr)
-        self.assertEqual(sim.cr, SelectableInt(0xffffffff, 32))
+        self.assertEqual(sim.cr, SelectableInt(0xf, 32))
+        print ("cr0", sim.crl[0])
+        self.assertTrue(SelectableInt(0xf, 4) == sim.crl[0])
 
     def run_tst_program(self, prog, initial_regs=[0] * 32):
         simulator = self.run_tst(prog, initial_regs)
index e413f4d6c8f5fb6f73c9062d1b2a29c1e7e39251..b5803d8818ced3b43b298a3b2ef6204c7d21c00b 100644 (file)
@@ -608,6 +608,7 @@ class PowerParser:
             self.op_fields.add(name)
         if name in ['CR', 'LR', 'CTR', 'TAR', 'FPSCR']:
             self.special_regs.add(name)
+            self.write_regs.add(name) # and add to list to write
         p[0] = ast.Name(id=name, ctx=ast.Load())
 
     def p_atom_number(self, p):
index 6be4ff5347460355eda511d0a86ee9e7f0975aba..7a1c3f5ec22fcd0aa675963ab385007ad82c1b4e 100644 (file)
@@ -55,6 +55,7 @@ class PyISAWriter(ISA):
                 pycode, rused = convert_to_python(pcode, d.form)
                 # create list of arguments to call
                 regs = list(rused['read_regs']) + list(rused['uninit_regs'])
+                regs += list(rused['special_regs'])
                 args = ', '.join(create_args(regs, 'self'))
                 # create list of arguments to return
                 retargs = ', '.join(create_args(rused['write_regs']))
index 392e33351b6fed326f55ad286056734fce7e1d4d..78cccc299e4f7b4c21e5e7f6be5ef399e55ef457 100644 (file)
@@ -22,6 +22,10 @@ class FieldSelectableInt:
             br = _br
         self.br = br # map of indices.
 
+    def eq(self, b):
+        self.si = copy(b.si)
+        self.br = copy(b.br)
+
     def _op(self, op, b):
         vi = self.get_range()
         vi = op(vi, b)
@@ -100,6 +104,10 @@ class SelectableInt:
         self.value = value & mask
         self.bits = bits
 
+    def eq(self, b):
+        self.value = b.value
+        self.bits = b.bits
+
     def __add__(self, b):
         if isinstance(b, int):
             b = SelectableInt(b, self.bits)
@@ -207,6 +215,8 @@ class SelectableInt:
             self.value = (self.value & ~mask) | (value & mask)
 
     def __ge__(self, other):
+        if isinstance(other, FieldSelectableInt):
+            other = other.get_range()
         if isinstance(other, SelectableInt):
             other = check_extsign(self, other)
             assert other.bits == self.bits
@@ -216,6 +226,8 @@ class SelectableInt:
         assert False
 
     def __le__(self, other):
+        if isinstance(other, FieldSelectableInt):
+            other = other.get_range()
         if isinstance(other, SelectableInt):
             other = check_extsign(self, other)
             assert other.bits == self.bits
@@ -225,6 +237,8 @@ class SelectableInt:
         assert False
 
     def __gt__(self, other):
+        if isinstance(other, FieldSelectableInt):
+            other = other.get_range()
         if isinstance(other, SelectableInt):
             other = check_extsign(self, other)
             assert other.bits == self.bits
@@ -234,6 +248,8 @@ class SelectableInt:
         assert False
 
     def __lt__(self, other):
+        if isinstance(other, FieldSelectableInt):
+            other = other.get_range()
         if isinstance(other, SelectableInt):
             other = check_extsign(self, other)
             assert other.bits == self.bits
@@ -243,6 +259,9 @@ class SelectableInt:
         assert False
 
     def __eq__(self, other):
+        print ("__eq__", self, other)
+        if isinstance(other, FieldSelectableInt):
+            other = other.get_range()
         if isinstance(other, SelectableInt):
             other = check_extsign(self, other)
             assert other.bits == self.bits