whoops missed some cases in unit test changing ALUHelpers
[soc.git] / src / soc / decoder / isa / test_caller.py
index 0e9c113185e53b053b1b6976948b26370e998d1f..b4689dd635f6e0231b2a775b5642c806743c8da5 100644 (file)
@@ -1,6 +1,6 @@
 from nmigen import Module, Signal
 from nmigen.back.pysim import Simulator, Delay
-from nmigen.test.utils import FHDLTestCase
+from nmutil.formaltest import FHDLTestCase
 import unittest
 from soc.decoder.isa.caller import ISACaller
 from soc.decoder.power_decoder import (create_pdecode)
@@ -19,21 +19,25 @@ class Register:
 
 class DecoderTestCase(FHDLTestCase):
 
-    def run_tst(self, generator, initial_regs):
+    def run_tst(self, generator, initial_regs, initial_sprs={}):
         m = Module()
         comb = m.d.comb
         instruction = Signal(32)
 
         pdecode = create_pdecode()
-        simulator = ISA(pdecode, initial_regs)
 
         m.submodules.pdecode2 = pdecode2 = PowerDecode2(pdecode)
+        simulator = ISA(pdecode2, initial_regs, initial_sprs, 0)
         comb += pdecode2.dec.raw_opcode_in.eq(instruction)
         sim = Simulator(m)
         gen = generator.generate_instructions()
 
         def process():
-            for ins, code in zip(gen, generator.assembly.splitlines()):
+            instructions = list(zip(gen, generator.assembly.splitlines()))
+
+            index = simulator.pc.CIA.value//4
+            while index < len(instructions):
+                ins, code = instructions[index]
 
                 print("0x{:X}".format(ins & 0xffffffff))
                 print(code)
@@ -44,6 +48,7 @@ class DecoderTestCase(FHDLTestCase):
                 yield Delay(1e-6)
                 opname = code.split(' ')[0]
                 yield from simulator.call(opname)
+                index = simulator.pc.CIA.value//4
 
         sim.add_process(process)
         with sim.write_vcd("simulator.vcd", "simulator.gtkw",
@@ -57,7 +62,7 @@ class DecoderTestCase(FHDLTestCase):
         initial_regs[3] = 0x1234
         initial_regs[2] = 0x4321
         with Program(lst) as program:
-            sim = self.run_test_program(program, initial_regs)
+            sim = self.run_tst_program(program, initial_regs)
             self.assertEqual(sim.gpr(1), SelectableInt(0x5555, 64))
 
     def test_addi(self):
@@ -65,7 +70,7 @@ class DecoderTestCase(FHDLTestCase):
                "addi 2, 0, 0x4321",
                "add  1, 3, 2"]
         with Program(lst) as program:
-            sim = self.run_test_program(program)
+            sim = self.run_tst_program(program)
             print(sim.gpr(1))
             self.assertEqual(sim.gpr(1), SelectableInt(0x5555, 64))
 
@@ -75,21 +80,228 @@ class DecoderTestCase(FHDLTestCase):
                "stw 2, 0(1)",
                "lwz 3, 0(1)"]
         with Program(lst) as program:
-            sim = self.run_test_program(program)
+            sim = self.run_tst_program(program)
             print(sim.gpr(1))
             self.assertEqual(sim.gpr(3), SelectableInt(0x1234, 64))
 
+    @unittest.skip("broken")
     def test_addpcis(self):
         lst = ["addpcis 1, 0x1",
                "addpcis 2, 0x1",
                "addpcis 3, 0x1"]
         with Program(lst) as program:
-            sim = self.run_test_program(program)
+            sim = self.run_tst_program(program)
             self.assertEqual(sim.gpr(1), SelectableInt(0x10004, 64))
             self.assertEqual(sim.gpr(2), SelectableInt(0x10008, 64))
             self.assertEqual(sim.gpr(3), SelectableInt(0x1000c, 64))
 
-    def run_test_program(self, prog, initial_regs=[0] * 32):
+    def test_branch(self):
+        lst = ["ba 0xc",             # branch to line 4
+               "addi 1, 0, 0x1234",  # Should never execute
+               "ba 0x1000",          # exit the program
+               "addi 2, 0, 0x1234",  # line 4
+               "ba 0x8"]             # branch to line 3
+        with Program(lst) as program:
+            sim = self.run_tst_program(program)
+            self.assertEqual(sim.pc.CIA, SelectableInt(0x1000, 64))
+            self.assertEqual(sim.gpr(1), SelectableInt(0x0, 64))
+            self.assertEqual(sim.gpr(2), SelectableInt(0x1234, 64))
+
+    def test_branch_link(self):
+        lst = ["bl 0xc",
+               "addi 2, 1, 0x1234",
+               "ba 0x1000",
+               "addi 1, 0, 0x1234",
+               "bclr 20, 0, 0"]
+        with Program(lst) as program:
+            sim = self.run_tst_program(program)
+            self.assertEqual(sim.spr['LR'], SelectableInt(0x4, 64))
+
+    def test_branch_ctr(self):
+        lst = ["addi 1, 0, 0x10",    # target of jump
+               "mtspr 9, 1",         # mtctr 1
+               "bcctr 20, 0, 0",     # bctr
+               "addi 2, 0, 0x1",     # should never execute
+               "addi 1, 0, 0x1234"]  # target of ctr
+        with Program(lst) as program:
+            sim = self.run_tst_program(program)
+            self.assertEqual(sim.spr['CTR'], SelectableInt(0x10, 64))
+            self.assertEqual(sim.gpr(1), SelectableInt(0x1234, 64))
+            self.assertEqual(sim.gpr(2), SelectableInt(0, 64))
+
+    def test_branch_cond(self):
+        for i in [0, 10]:
+            lst = [f"addi 1, 0, {i}",  # set r1 to i
+                "cmpi cr0, 1, 1, 10",  # compare r1 with 10 and store to cr0
+                "bc 12, 2, 0x8",       # beq 0x8 -
+                                       # branch if r1 equals 10 to the nop below
+                "addi 2, 0, 0x1234",   # if r1 == 10 this shouldn't execute
+                "or 0, 0, 0"]          # branch target
+            with Program(lst) as program:
+                sim = self.run_tst_program(program)
+                if i == 10:
+                    self.assertEqual(sim.gpr(2), SelectableInt(0, 64))
+                else:
+                    self.assertEqual(sim.gpr(2), SelectableInt(0x1234, 64))
+
+    def test_branch_loop(self):
+        lst = ["addi 1, 0, 0",
+               "addi 1, 0, 0",
+               "addi 1, 1, 1",
+               "add  2, 2, 1",
+               "cmpi cr0, 1, 1, 10",
+               "bc 12, 0, -0xc"]
+        with Program(lst) as program:
+            sim = self.run_tst_program(program)
+            # Verified with qemu
+            self.assertEqual(sim.gpr(2), SelectableInt(0x37, 64))
+
+    def test_branch_loop_ctr(self):
+        lst = ["addi 1, 0, 0",
+               "addi 2, 0, 7",
+               "mtspr 9, 2",    # set ctr to 7
+               "addi 1, 1, 5",
+               "bc 16, 0, -0x4"]  # bdnz to the addi above
+        with Program(lst) as program:
+            sim = self.run_tst_program(program)
+            # Verified with qemu
+            self.assertEqual(sim.gpr(1), SelectableInt(0x23, 64))
+
+
+
+    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)
+            # Verified with QEMU
+            self.assertEqual(sim.gpr(3), SelectableInt(0x80000000, 64))
+
+    def test_cmp(self):
+        lst = ["addis 1, 0, 0xffff",
+               "addis 2, 0, 0xffff",
+               "cmp cr2, 0, 1, 2",
+               "mfcr 3"]
+        with Program(lst) as program:
+            sim = self.run_tst_program(program)
+            self.assertEqual(sim.gpr(3), SelectableInt(0x200000, 64))
+
+    def test_slw(self):
+        lst = ["slw 1, 3, 2"]
+        initial_regs = [0] * 32
+        initial_regs[3] = 0xdeadbeefcafebabe
+        initial_regs[2] = 5
+        with Program(lst) as program:
+            sim = self.run_tst_program(program, initial_regs)
+            self.assertEqual(sim.gpr(1), SelectableInt(0x5fd757c0, 64))
+
+    def test_srw(self):
+        lst = ["srw 1, 3, 2"]
+        initial_regs = [0] * 32
+        initial_regs[3] = 0xdeadbeefcafebabe
+        initial_regs[2] = 5
+        with Program(lst) as program:
+            sim = self.run_tst_program(program, initial_regs)
+            self.assertEqual(sim.gpr(1), SelectableInt(0x657f5d5, 64))
+
+    def test_rlwinm(self):
+        lst = ["rlwinm 3, 1, 5, 20, 6"]
+        initial_regs = [0] * 32
+        initial_regs[1] = -1
+        with Program(lst) as program:
+            sim = self.run_tst_program(program, initial_regs)
+            self.assertEqual(sim.gpr(3), SelectableInt(0xfffffffffe000fff, 64))
+
+    def test_rlwimi(self):
+        lst = ["rlwimi 3, 1, 5, 20, 6"]
+        initial_regs = [0] * 32
+        initial_regs[1] = 0xffffffffdeadbeef
+        initial_regs[3] = 0x12345678
+        with Program(lst) as program:
+            sim = self.run_tst_program(program, initial_regs)
+            self.assertEqual(sim.gpr(3), SelectableInt(0xd5b7ddfbd4345dfb, 64))
+
+    def test_rldic(self):
+        lst = ["rldic 3, 1, 5, 20"]
+        initial_regs = [0] * 32
+        initial_regs[1] = 0xdeadbeefcafec0de
+        with Program(lst) as program:
+            sim = self.run_tst_program(program, initial_regs)
+            self.assertEqual(sim.gpr(3), SelectableInt(0xdf95fd81bc0, 64))
+
+    def test_prty(self):
+        lst = ["prtyw 2, 1"]
+        initial_regs = [0] * 32
+        initial_regs[1] = 0xdeadbeeecaffc0de
+        with Program(lst) as program:
+            sim = self.run_tst_program(program, initial_regs)
+            self.assertEqual(sim.gpr(2), SelectableInt(0x100000001, 64))
+
+    def test_popcnt(self):
+        lst = ["popcntb 2, 1",
+               "popcntw 3, 1",
+               "popcntd 4, 1"
+        ]
+        initial_regs = [0] * 32
+        initial_regs[1] = 0xdeadbeefcafec0de
+        with Program(lst) as program:
+            sim = self.run_tst_program(program, initial_regs)
+            self.assertEqual(sim.gpr(2),
+                             SelectableInt(0x605060704070206, 64))
+            self.assertEqual(sim.gpr(3),
+                             SelectableInt(0x1800000013, 64))
+            self.assertEqual(sim.gpr(4),
+                             SelectableInt(0x2b, 64))
+
+    def test_cntlz(self):
+        lst = ["cntlzd 2, 1",
+               "cntlzw 4, 3"]
+        initial_regs = [0] * 32
+        initial_regs[1] = 0x0000beeecaffc0de
+        initial_regs[3] = 0x0000000000ffc0de
+        with Program(lst) as program:
+            sim = self.run_tst_program(program, initial_regs)
+            self.assertEqual(sim.gpr(2), SelectableInt(16, 64))
+            self.assertEqual(sim.gpr(4), SelectableInt(8, 64))
+
+    def test_cmpeqb(self):
+        lst = ["cmpeqb cr0, 2, 1",
+               "cmpeqb cr1, 3, 1"]
+        initial_regs = [0] * 32
+        initial_regs[1] = 0x0102030405060708
+        initial_regs[2] = 0x04
+        initial_regs[3] = 0x10
+        with Program(lst) as program:
+            sim = self.run_tst_program(program, initial_regs)
+            self.assertEqual(sim.crl[0].get_range().value,
+                             SelectableInt(4, 4))
+            self.assertEqual(sim.crl[1].get_range().value,
+                             SelectableInt(0, 4))
+        
+        
+
+    def test_mtcrf(self):
+        for i in range(4):
+            # 0x76540000 gives expected (3+4) (2+4) (1+4) (0+4) for
+            #     i=0, 1, 2, 3
+            # The positions of the CR fields have been verified using
+            # QEMU and 'cmp crx, a, b' instructions
+            lst = ["addis 1, 0, 0x7654",
+                   "mtcrf %d, 1" % (1 << (7-i)),
+                   ]
+            with Program(lst) as program:
+                sim = self.run_tst_program(program)
+            print("cr", sim.cr)
+            expected = (7-i)
+            # check CR itself
+            self.assertEqual(sim.cr, SelectableInt(expected << ((7-i)*4), 32))
+            # check CR[0]/1/2/3 as well
+            print("cr%d", sim.crl[i])
+            self.assertTrue(SelectableInt(expected, 4) == sim.crl[i])
+
+    def run_tst_program(self, prog, initial_regs=[0] * 32):
         simulator = self.run_tst(prog, initial_regs)
         simulator.gpr.dump()
         return simulator