From: Michael Nolan Date: Thu, 7 May 2020 15:40:31 +0000 (-0400) Subject: Add handling of add with comparison X-Git-Tag: div_pipeline~1359 X-Git-Url: https://git.libre-soc.org/?p=soc.git;a=commitdiff_plain;h=76a6f7d5099f4999bdf3bc061a0e9a1f1208212e Add handling of add with comparison --- diff --git a/src/soc/decoder/isa/caller.py b/src/soc/decoder/isa/caller.py index cf66b95b..a5712320 100644 --- a/src/soc/decoder/isa/caller.py +++ b/src/soc/decoder/isa/caller.py @@ -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.helpers import exts 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): - 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 - self.decoder = decoder2 + self.decoder = decoder2.dec + self.dec2 = decoder2 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) + 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 @@ -258,6 +283,12 @@ class ISACaller: 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) diff --git a/src/soc/decoder/isa/test_caller.py b/src/soc/decoder/isa/test_caller.py index 78766f6c..14beb2a7 100644 --- a/src/soc/decoder/isa/test_caller.py +++ b/src/soc/decoder/isa/test_caller.py @@ -25,9 +25,9 @@ class DecoderTestCase(FHDLTestCase): instruction = Signal(32) pdecode = create_pdecode() - simulator = ISA(pdecode, initial_regs) 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() @@ -128,11 +128,25 @@ class DecoderTestCase(FHDLTestCase): 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) - 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):