Add handling of add with comparison
authorMichael Nolan <mtnolan2640@gmail.com>
Thu, 7 May 2020 15:40:31 +0000 (11:40 -0400)
committerMichael Nolan <mtnolan2640@gmail.com>
Thu, 7 May 2020 15:41:42 +0000 (11:41 -0400)
src/soc/decoder/isa/caller.py
src/soc/decoder/isa/test_caller.py

index cf66b95bd624f3c1e93f01c7beaf34ad0f276f4f..a5712320aeb52d1005eae62b4b063e58c24cc07d 100644 (file)
@@ -3,6 +3,7 @@ from soc.decoder.orderedset import OrderedSet
 from soc.decoder.selectable_int import (FieldSelectableInt, SelectableInt,
                                         selectconcat)
 from soc.decoder.power_enums import spr_dict
 from soc.decoder.selectable_int import (FieldSelectableInt, SelectableInt,
                                         selectconcat)
 from soc.decoder.power_enums import spr_dict
+from soc.decoder.helpers import exts
 from collections import namedtuple
 import math
 
 from collections import namedtuple
 import math
 
@@ -203,12 +204,13 @@ class ISACaller:
         # field-selectable versions of Condition Register TODO check bitranges?
         self.crl = []
         for i in range(8):
         # field-selectable versions of Condition Register TODO check bitranges?
         self.crl = []
         for i in range(8):
-            bits = tuple(range((7-i)*4, (8-i)*4))# errr... maybe?
+            bits = tuple(range(i*4, (i+1)*4))# errr... maybe?
             _cr = FieldSelectableInt(self.cr, bits)
             self.crl.append(_cr)
             self.namespace["CR%d" % i] = _cr
 
             _cr = FieldSelectableInt(self.cr, bits)
             self.crl.append(_cr)
             self.namespace["CR%d" % i] = _cr
 
-        self.decoder = decoder2
+        self.decoder = decoder2.dec
+        self.dec2 = decoder2
 
     def memassign(self, ea, sz, val):
         self.mem.memassign(ea, sz, val)
 
     def memassign(self, ea, sz, val):
         self.mem.memassign(ea, sz, val)
@@ -228,6 +230,29 @@ class ISACaller:
             val = yield sig
             self.namespace[name] = SelectableInt(val, sig.width)
 
             val = yield sig
             self.namespace[name] = SelectableInt(val, sig.width)
 
+    def handle_carry(self, inputs, outputs):
+        inv_a = yield self.dec2.invert_a
+        if inv_a:
+            inputs[0] = ~inputs[0]
+        assert len(outputs) >= 1
+        output = outputs[0]
+        gts = [(x > output) == SelectableInt(1, 1) for x in inputs]
+        print(gts)
+        if all(gts):
+            return True
+        return False
+
+    def handle_comparison(self, outputs):
+        out = outputs[0]
+        out = exts(out.value, out.bits)
+        zero = SelectableInt(out == 0, 1)
+        positive = SelectableInt(out > 0, 1)
+        negative = SelectableInt(out < 0, 1)
+        SO = SelectableInt(0, 1)
+        cr_field = selectconcat(negative, positive, zero, SO)
+        self.crl[0].eq(cr_field)
+        
+
     def call(self, name):
         # TODO, asmregs is from the spec, e.g. add RT,RA,RB
         # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
     def call(self, name):
         # TODO, asmregs is from the spec, e.g. add RT,RA,RB
         # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
@@ -258,6 +283,12 @@ class ISACaller:
         results = info.func(self, *inputs)
         print(results)
 
         results = info.func(self, *inputs)
         print(results)
 
+        carry_en = yield self.dec2.e.rc.data
+        if carry_en:
+            cy = self.handle_carry(inputs, results)
+
+            self.handle_comparison(results)
+
         # any modified return results?
         if info.write_regs:
             output_names = create_args(info.write_regs)
         # any modified return results?
         if info.write_regs:
             output_names = create_args(info.write_regs)
index 78766f6c0d608556c6200ecfb5e76c71e55b9baf..14beb2a7068e892826cb3f26bf4afb3397846b89 100644 (file)
@@ -25,9 +25,9 @@ class DecoderTestCase(FHDLTestCase):
         instruction = Signal(32)
 
         pdecode = create_pdecode()
         instruction = Signal(32)
 
         pdecode = create_pdecode()
-        simulator = ISA(pdecode, initial_regs)
 
         m.submodules.pdecode2 = pdecode2 = PowerDecode2(pdecode)
 
         m.submodules.pdecode2 = pdecode2 = PowerDecode2(pdecode)
+        simulator = ISA(pdecode2, initial_regs)
         comb += pdecode2.dec.raw_opcode_in.eq(instruction)
         sim = Simulator(m)
         gen = generator.generate_instructions()
         comb += pdecode2.dec.raw_opcode_in.eq(instruction)
         sim = Simulator(m)
         gen = generator.generate_instructions()
@@ -128,11 +128,25 @@ class DecoderTestCase(FHDLTestCase):
             self.assertEqual(sim.gpr(1), SelectableInt(0x1234, 64))
             self.assertEqual(sim.gpr(2), SelectableInt(0, 64))
 
             self.assertEqual(sim.gpr(1), SelectableInt(0x1234, 64))
             self.assertEqual(sim.gpr(2), SelectableInt(0, 64))
 
-    def test_mfcr(self):
-        lst = ["mfcr 1"]
+    def test_add_compare(self):
+        lst = ["addis 1, 0, 0xffff",
+               "addis 2, 0, 0xffff",
+               "add. 1, 1, 2",
+               "mfcr 3"]
         with Program(lst) as program:
             sim = self.run_tst_program(program)
         with Program(lst) as program:
             sim = self.run_tst_program(program)
-            self.assertEqual(sim.gpr(1), SelectableInt(0, 64))
+            # Verified with QEMU
+            self.assertEqual(sim.gpr(3), SelectableInt(0x80000000, 64))
+
+    @unittest.skip("broken (XER)")
+    def test_cmp(self):
+        lst = ["addis 1, 0, 0xffff",
+               "addis 2, 0, 0xffff",
+               "cmp cr0, 0, 1, 2",
+               "mfcr 3"]
+        with Program(lst) as program:
+            sim = self.run_tst_program(program)
+            self.assertEqual(sim.gpr(3), SelectableInt(0x20000000, 64))
 
     def test_mtcrf(self):
         for i in range(4):
 
     def test_mtcrf(self):
         for i in range(4):