X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fsoc%2Fdecoder%2Fisa%2Ftest_caller.py;h=ea2bca9ed71752015787f3f3d81bdf19ac300dda;hb=7bcc2eb604806b9b69993974cb0b5519136a7d01;hp=b958795c147f3ca5267e67a252eb58534a867948;hpb=237d4f455ae825941b0542819c02fdc87585808a;p=soc.git diff --git a/src/soc/decoder/isa/test_caller.py b/src/soc/decoder/isa/test_caller.py index b958795c..ea2bca9e 100644 --- a/src/soc/decoder/isa/test_caller.py +++ b/src/soc/decoder/isa/test_caller.py @@ -6,33 +6,10 @@ from soc.decoder.isa.caller import ISACaller from soc.decoder.power_decoder import (create_pdecode) from soc.decoder.power_decoder2 import (PowerDecode2) from soc.simulator.program import Program -from soc.simulator.qemu import run_program from soc.decoder.isa.caller import ISACaller, inject -from soc.decoder.helpers import (EXTS64, EXTZ64, ROTL64, ROTL32, MASK,) from soc.decoder.selectable_int import SelectableInt -from soc.decoder.selectable_int import selectconcat as concat from soc.decoder.orderedset import OrderedSet - -class fixedarith(ISACaller): - - @inject() - def op_addi(self, RA): - if RA == 0: - RT = SI - else: - RT = RA + SI - return (RT,) - @inject() - def op_add(self, RA, RB): - RT = RA + RB - return (RT,) - - instrs = {} - instrs['addi'] = (op_addi, OrderedSet(['RA']), - OrderedSet(), OrderedSet(['RT'])) - instrs['add'] = (op_add, OrderedSet(['RA', 'RB']), - OrderedSet(), OrderedSet(['RT'])) - +from soc.decoder.isa.all import ISA class Register: @@ -42,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 = fixedarith(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) @@ -67,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", @@ -80,11 +62,250 @@ class DecoderTestCase(FHDLTestCase): initial_regs[3] = 0x1234 initial_regs[2] = 0x4321 with Program(lst) as program: - 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): + lst = ["addi 3, 0, 0x1234", + "addi 2, 0, 0x4321", + "add 1, 3, 2"] + with Program(lst) as program: + sim = self.run_tst_program(program) + print(sim.gpr(1)) + self.assertEqual(sim.gpr(1), SelectableInt(0x5555, 64)) + + def test_load_store(self): + lst = ["addi 1, 0, 0x0010", + "addi 2, 0, 0x1234", + "stw 2, 0(1)", + "lwz 3, 0(1)"] + with Program(lst) as 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_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 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 run_test_program(self, prog, initial_regs): + 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) - print(simulator.gpr) + simulator.gpr.dump() + return simulator + if __name__ == "__main__": unittest.main()