attempting to add overflow setting in ISACaller
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Mon, 29 Jun 2020 13:29:27 +0000 (14:29 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Mon, 29 Jun 2020 13:29:27 +0000 (14:29 +0100)
libreriscv
src/soc/decoder/isa/caller.py
src/soc/decoder/pseudo/parser.py
src/soc/simulator/test_div_sim.py

index b4a37081cfd2985ffa7678597f2dd459c39c72ff..2f5dd53ca00e1d3566ae7bddad175743f28f0a08 160000 (submodule)
@@ -1 +1 @@
-Subproject commit b4a37081cfd2985ffa7678597f2dd459c39c72ff
+Subproject commit 2f5dd53ca00e1d3566ae7bddad175743f28f0a08
index b3b2c17132db8afbc299e8ee50f23e18635f884f..943e65b7a1303090b4c6b25dd9ddf2426ff9fffe 100644 (file)
@@ -270,6 +270,7 @@ class ISACaller:
 
         # "undefined", just set to variable-bit-width int (use exts "max")
         self.undefined = SelectableInt(0, 256) # TODO, not hard-code 256!
+        self._overflow = None
 
         self.namespace = {'GPR': self.gpr,
                           'MEM': self.mem,
@@ -280,6 +281,7 @@ class ISACaller:
                           'CR': self.cr,
                           'MSR': self.msr,
                           'undefined': self.undefined,
+                          'overflow': self._overflow,
                           'mode_is_64bit': True,
                           'SO': XER_bits['SO']
                           }
@@ -328,6 +330,7 @@ class ISACaller:
         self.namespace['XER'] = self.spr['XER']
         self.namespace['CA'] = self.spr['XER'][XER_bits['CA']].value
         self.namespace['CA32'] = self.spr['XER'][XER_bits['CA32']].value
+        self.namespace['overflow'] = None
 
     def handle_carry_(self, inputs, outputs, already_done):
         inv_a = yield self.dec2.e.invert_a
@@ -527,10 +530,20 @@ class ISACaller:
         carry_en = yield self.dec2.e.output_carry
         if carry_en:
             yield from self.handle_carry_(inputs, results, already_done)
+
+        # detect if overflow was in return result
+        overflow = None
+        if info.write_regs:
+            for name, output in zip(output_names, results):
+                if name == 'overflow':
+                    self._overflow = output
+
         ov_en = yield self.dec2.e.oe.oe
         ov_ok = yield self.dec2.e.oe.ok
+        print ("internal overflow", self._overflow)
         if ov_en & ov_ok:
             yield from self.handle_overflow(inputs, results)
+
         rc_en = yield self.dec2.e.rc.data
         if rc_en:
             self.handle_comparison(results)
@@ -538,6 +551,8 @@ class ISACaller:
         # any modified return results?
         if info.write_regs:
             for name, output in zip(output_names, results):
+                if name == 'overflow': # ignore, done already (above)
+                    continue
                 if isinstance(output, int):
                     output = SelectableInt(output, 256)
                 if name in ['CA', 'CA32']:
index 8bdcd86816b6e7ee687f3f5ad38d663adb1eae6a..ddd49fabeeb9c4fff5edb6623d37a4c664d0d965 100644 (file)
@@ -661,6 +661,8 @@ class PowerParser:
         name = p[1]
         if name in self.available_op_fields:
             self.op_fields.add(name)
+        if name == 'overflow':
+            self.write_regs.add(name)
         if self.include_ca_in_write:
             if name in ['CA', 'CA32']:
                 self.write_regs.add(name)
index acaeed7a5a450889f3797a6a8b9937d3cfb2f5b8..37d0dc7ca4982a414cb5005df6a667d856db02bb 100644 (file)
@@ -20,7 +20,7 @@ from soc.simulator.test_sim import DecoderBase
 class DivTestCases(FHDLTestCase):
     test_data = []
 
-    def __init__(self, name="general"):
+    def __init__(self, name="div"):
         super().__init__(name)
         self.test_name = name
 
@@ -32,7 +32,24 @@ class DivTestCases(FHDLTestCase):
         with Program(lst) as program:
             self.run_tst_program(program, [1, 2, 3])
 
-    def test_1_divw_byzero(self):
+    def test_1_divwe(self):
+        lst = ["addi 1, 0, 0x5678",
+               "addi 2, 0, 0x1234",
+               "divwe  3, 1, 2",
+               ]
+        with Program(lst) as program:
+            self.run_tst_program(program, [1, 2, 3])
+
+    def test_2_divweu(self):
+        lst = ["addi 1, 0, 0x5678",
+               "addi 2, 0, 0x1234",
+               "divweu  3, 1, 2",
+               ]
+        with Program(lst) as program:
+            self.run_tst_program(program, [1, 2, 3])
+
+    @unittest.skip("qemu_wrong_result")
+    def test_3_divwo_byzero(self):
         lst = ["addi 1, 0, 0x5678",
                "addi 2, 0, 0x0",
                "divw  3, 1, 2",
@@ -40,7 +57,7 @@ class DivTestCases(FHDLTestCase):
         with Program(lst) as program:
             self.run_tst_program(program, [1, 2, 3])
 
-    def test_2_moduw(self):
+    def test_4_moduw(self):
         lst = ["addi 1, 0, 0x5678",
                "addi 2, 0, 0x1234",
                "moduw  3, 1, 2",