From d4c48b021080f845f568403ff30f65061375e761 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Sat, 15 May 2021 16:57:27 +0100 Subject: [PATCH] add fmr test and associated decoder (optional with include_fp) --- src/openpower/decoder/isa/caller.py | 6 ++- src/openpower/decoder/isa/test_caller.py | 4 +- src/openpower/decoder/isa/test_caller_fp.py | 27 ++++++++-- src/openpower/decoder/power_decoder.py | 59 ++++++++++++--------- 4 files changed, 63 insertions(+), 33 deletions(-) diff --git a/src/openpower/decoder/isa/caller.py b/src/openpower/decoder/isa/caller.py index 61af16c6..eec3b08f 100644 --- a/src/openpower/decoder/isa/caller.py +++ b/src/openpower/decoder/isa/caller.py @@ -858,10 +858,12 @@ class ISACaller: # TODO, asmregs is from the spec, e.g. add RT,RA,RB # see http://bugs.libre-riscv.org/show_bug.cgi?id=282 dec_insn = yield self.dec2.e.do.insn + insn_1_11 = yield self.dec2.e.do.insn[1:11] asmcode = yield self.dec2.dec.op.asmcode - print("get assembly name asmcode", asmcode, hex(dec_insn)) - asmop = insns.get(asmcode, None) int_op = yield self.dec2.dec.op.internal_op + print("get assembly name asmcode", asmcode, int_op, + hex(dec_insn), bin(insn_1_11)) + asmop = insns.get(asmcode, None) # sigh reconstruct the assembly instruction name if hasattr(self.dec2.e.do, "oe"): diff --git a/src/openpower/decoder/isa/test_caller.py b/src/openpower/decoder/isa/test_caller.py index efb6275f..8fd5e5fd 100644 --- a/src/openpower/decoder/isa/test_caller.py +++ b/src/openpower/decoder/isa/test_caller.py @@ -3,7 +3,7 @@ from nmigen.back.pysim import Simulator, Delay, Settle from nmutil.formaltest import FHDLTestCase import unittest from openpower.decoder.isa.caller import ISACaller -from openpower.decoder.power_decoder import (create_pdecode) +from openpower.decoder.power_decoder import create_pdecode from openpower.decoder.power_decoder2 import (PowerDecode2) from openpower.simulator.program import Program from openpower.decoder.isa.caller import ISACaller, inject @@ -25,7 +25,7 @@ def run_tst(generator, initial_regs, initial_sprs=None, svstate=0, mmu=False, comb = m.d.comb instruction = Signal(32) - pdecode = create_pdecode() + pdecode = create_pdecode(include_fp=initial_fprs is not None) gen = list(generator.generate_instructions()) insncode = generator.assembly.splitlines() diff --git a/src/openpower/decoder/isa/test_caller_fp.py b/src/openpower/decoder/isa/test_caller_fp.py index 79da6467..9434f6ae 100644 --- a/src/openpower/decoder/isa/test_caller_fp.py +++ b/src/openpower/decoder/isa/test_caller_fp.py @@ -22,7 +22,7 @@ class DecoderTestCase(FHDLTestCase): for i in range(32): self.assertEqual(sim.fpr(i), SelectableInt(expected_fpr[i], 64)) - def test_fpload(self): + def tst_fpload(self): """>>> lst = ["lfsx 1, 0, 0", ] """ @@ -38,7 +38,7 @@ class DecoderTestCase(FHDLTestCase): print("FPR 1", sim.fpr(1)) self.assertEqual(sim.fpr(1), SelectableInt(0x4040266660000000, 64)) - def test_fp_single_ldst(self): + def tst_fp_single_ldst(self): """>>> lst = ["lfsx 1, 1, 0", # load fp 1 from mem location 0 "stfsu 1, 16(1)", # store fp 1 into mem 0x10, update RA "lfsu 2, 0(1)", # re-load from UPDATED r1 @@ -62,11 +62,30 @@ class DecoderTestCase(FHDLTestCase): self.assertEqual(sim.fpr(1), SelectableInt(0x4040266660000000, 64)) self.assertEqual(sim.fpr(2), SelectableInt(0x4040266660000000, 64)) + def test_fp_mv(self): + """>>> lst = ["fmr 1, 2", + ] + """ + lst = ["fmr 1, 2", + ] + + fprs = [0] * 32 + fprs[2] = 0x4040266660000000 + + with Program(lst, bigendian=False) as program: + sim = self.run_tst_program(program, initial_fprs=fprs) + print("FPR 1", sim.fpr(1)) + print("FPR 2", sim.fpr(2)) + self.assertEqual(sim.fpr(1), SelectableInt(0x4040266660000000, 64)) + self.assertEqual(sim.fpr(2), SelectableInt(0x4040266660000000, 64)) + def run_tst_program(self, prog, initial_regs=None, - initial_mem=None): + initial_mem=None, + initial_fprs=None): if initial_regs is None: initial_regs = [0] * 32 - simulator = run_tst(prog, initial_regs, mem=initial_mem) + simulator = run_tst(prog, initial_regs, mem=initial_mem, + initial_fprs=initial_fprs) print ("GPRs") simulator.gpr.dump() print ("FPRs") diff --git a/src/openpower/decoder/power_decoder.py b/src/openpower/decoder/power_decoder.py index 7cf61af1..35fa6231 100644 --- a/src/openpower/decoder/power_decoder.py +++ b/src/openpower/decoder/power_decoder.py @@ -236,6 +236,11 @@ class PowerOp: if False: print(row.keys()) asmcode = row['comment'] + # process the comment field, strip out "equals" for FP + if "=" in asmcode: + asmcode = asmcode.split("=")[-1] + print ("asmcode stripping =", asmcode, + asmcode in asmidx, hasattr(self, "asmcode")) if hasattr(self, "asmcode") and asmcode in asmidx: res.append(self.asmcode.eq(asmidx[asmcode])) for bit in single_bit_flags: @@ -410,26 +415,27 @@ class PowerDecoder(Elaboratable): def handle_subdecoders(self, switch_case, submodules, d): eqs = [] - for dec in d.subdecoders: - if isinstance(dec, list): # XXX HACK: take first pattern - dec = dec[0] - #print("subdec", dec.pattern, self.pname) - mname = get_pname("dec%d" % dec.pattern, self.pname) - if mname in submodules: - # sigh, HACK... - mname += "_1" - assert mname not in submodules - subdecoder = PowerDecoder(self.width, dec, - name=mname, - col_subset=self.col_subset, - row_subset=self.row_subsetfn) - if not subdecoder.tree_analyse(): # doesn't do anything - del subdecoder - continue # skip - submodules[mname] = subdecoder - eqs.append(subdecoder.opcode_in.eq(self.opcode_in)) - switch_case[dec.pattern] = self.op.eq(subdecoder.op) - self.actually_does_something = True + for dlist in d.subdecoders: + if not isinstance(dlist, list): # XXX HACK: take first pattern + dlist = [dlist] + for dec in dlist: + #print("subdec", dec.pattern, self.pname) + mname = get_pname("dec%d" % dec.pattern, self.pname) + if mname in submodules: + # sigh, HACK... + mname += "_1" + assert mname not in submodules + subdecoder = PowerDecoder(self.width, dec, + name=mname, + col_subset=self.col_subset, + row_subset=self.row_subsetfn) + if not subdecoder.tree_analyse(): # doesn't do anything + del subdecoder + continue # skip + submodules[mname] = subdecoder + eqs.append(subdecoder.opcode_in.eq(self.opcode_in)) + switch_case[dec.pattern] = self.op.eq(subdecoder.op) + self.actually_does_something = True return eqs @@ -539,6 +545,7 @@ def create_pdecode(name=None, col_subset=None, row_subset=None, subsetting of the PowerOp decoding is possible by setting col_subset """ + print ("create_pdecode", name, col_subset, row_subset, include_fp) # some alteration to the CSV files is required for SV so we use # a class to do it @@ -571,12 +578,14 @@ def create_pdecode(name=None, col_subset=None, row_subset=None, # FP 63L/H decoders. TODO: move mffsfamily to separate subdecoder if include_fp: - pminor.append(Subdecoder(pattern=63, opcodes=get_csv("minor_63l.csv"), - opint=True, bitsel=(1, 11), suffix=None, - subdecoders=[])) - pminor.append(Subdecoder(pattern=63, opcodes=get_csv("minor_63h.csv"), + pminor.append( + [Subdecoder(pattern=63, opcodes=get_csv("minor_63h.csv"), opint=True, bitsel=(1, 6), suffix=None, - subdecoders=[])) + subdecoders=[]), + Subdecoder(pattern=63, opcodes=get_csv("minor_63l.csv"), + opint=True, bitsel=(1, 11), suffix=None, + subdecoders=[]) + ]) # top level: extra merged with major dec = [] -- 2.30.2