Add checks for Byte-Reverse instructions.

main
Jean-François Nguyen 2 years ago
parent 4bf2398208
commit ae76adefbf

@ -8,3 +8,6 @@ from .rotate import *
from .bcd import * from .bcd import *
from .msr import * from .msr import *
from .spr import * from .spr import *

# TODO: add a --exclude= argument to the 'check' command
# from .byterev import *

@ -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

@ -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 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)) 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 # Move To/From System Register


class MTMSR (WordInsn): _fields = (f.PO(31), f.RS(), f.L_X15(), f.XO_X(146)) class MTMSR (WordInsn): _fields = (f.PO(31), f.RS(), f.L_X15(), f.XO_X(146))

@ -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
Loading…
Cancel
Save