From ae76adefbf2f1129eca4d81b032573efa0434977 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Nguyen?= Date: Mon, 18 Jul 2022 15:07:42 +0200 Subject: [PATCH] Add checks for Byte-Reverse instructions. --- power_fv/check/insn/all.py | 3 ++ power_fv/check/insn/byterev.py | 10 +++++++ power_fv/insn/const.py | 5 ++++ power_fv/insn/spec/byterev.py | 51 ++++++++++++++++++++++++++++++++++ 4 files changed, 69 insertions(+) create mode 100644 power_fv/check/insn/byterev.py create mode 100644 power_fv/insn/spec/byterev.py diff --git a/power_fv/check/insn/all.py b/power_fv/check/insn/all.py index 452f080..a30781a 100644 --- a/power_fv/check/insn/all.py +++ b/power_fv/check/insn/all.py @@ -8,3 +8,6 @@ from .rotate import * from .bcd import * from .msr import * from .spr import * + +# TODO: add a --exclude= argument to the 'check' command +# from .byterev import * diff --git a/power_fv/check/insn/byterev.py b/power_fv/check/insn/byterev.py new file mode 100644 index 0000000..4fdea36 --- /dev/null +++ b/power_fv/check/insn/byterev.py @@ -0,0 +1,10 @@ +from power_fv.insn import const +from power_fv.insn.spec.byterev import ByteReverseSpec +from power_fv.check.insn import InsnCheck + + +__all__ = ["BRH", "BRW"] + + +class BRH(InsnCheck, spec_cls=ByteReverseSpec, insn_cls=const.BRH): pass +class BRW(InsnCheck, spec_cls=ByteReverseSpec, insn_cls=const.BRW): pass diff --git a/power_fv/insn/const.py b/power_fv/insn/const.py index 27299e5..b32cd1a 100644 --- a/power_fv/insn/const.py +++ b/power_fv/insn/const.py @@ -197,6 +197,11 @@ class CDTBCD (WordInsn): _fields = (f.PO(31), f.RS(), f.RA(), f.XO_X(28 class CBCDTD (WordInsn): _fields = (f.PO(31), f.RS(), f.RA(), f.XO_X(314)) class ADDG6S (WordInsn): _fields = (f.PO(31), f.RT(), f.RA(), f.RB(), f.XO(74)) +# Byte-Reverse + +class BRH (WordInsn): _fields = (f.PO(31), f.RS(), f.RA(), f.XO_X(219)) +class BRW (WordInsn): _fields = (f.PO(31), f.RS(), f.RA(), f.XO_X(155)) + # Move To/From System Register class MTMSR (WordInsn): _fields = (f.PO(31), f.RS(), f.L_X15(), f.XO_X(146)) diff --git a/power_fv/insn/spec/byterev.py b/power_fv/insn/spec/byterev.py new file mode 100644 index 0000000..ee1170b --- /dev/null +++ b/power_fv/insn/spec/byterev.py @@ -0,0 +1,51 @@ +from amaranth import * + +from power_fv import pfv +from power_fv.insn.const import * + +from . import InsnSpec +from .utils import iea, byte_reversed + + +__all__ = ["ByteReverseSpec"] + + +class ByteReverseSpec(InsnSpec, Elaboratable): + def __init__(self, insn): + self.pfv = pfv.Interface() + self.insn = insn + + def elaborate(self, platform): + m = Module() + + m.d.comb += [ + self.pfv.stb .eq(1), + self.pfv.insn.eq(Cat(Const(0, 32), self.insn.as_value())), + self.pfv.intr.eq(0), + self.pfv.nia .eq(iea(self.pfv.cia + 4, self.pfv.msr.r_data.sf)), + self.pfv.msr.r_mask.sf.eq(1), + ] + + m.d.comb += [ + self.pfv.rs.index.eq(self.insn.RS), + self.pfv.rs.r_stb.eq(1), + self.pfv.ra.index.eq(self.insn.RA), + self.pfv.ra.w_stb.eq(1), + ] + + if isinstance(self.insn, BRH): + for i in range(64//16): + rs_hword = self.pfv.rs.r_data.word_select(i, width=16) + ra_hword = self.pfv.ra.w_data.word_select(i, width=16) + m.d.comb += ra_hword.eq(byte_reversed(rs_hword, en=1)) + + elif isinstance(self.insn, BRW): + for i in range(64//32): + rs_word = self.pfv.rs.r_data.word_select(i, width=32) + ra_word = self.pfv.ra.w_data.word_select(i, width=32) + m.d.comb += ra_word.eq(byte_reversed(rs_word, en=1)) + + else: + assert False + + return m