Add checks for 64-bit Rotate/Shift instructions.

dinofly
Jean-François Nguyen 2 years ago
parent eb314fcbf0
commit 96878c73da

@ -4,9 +4,12 @@ from power_fv.check.insn import InsnCheck




__all__ = [ __all__ = [
"RLWINM", "RLWINM_", "RLWNM", "RLWNM_", "RLWIMI", "RLWIMI_", "RLWINM", "RLWINM_", "RLWNM" , "RLWNM_" , "RLWIMI", "RLWIMI_",
"SLW" , "SLW_" , "RLDICL", "RLDICL_", "RLDICR", "RLDICR_", "RLDIC" , "RLDIC_" ,
"SRW" , "SRW_" , "SRAWI", "SRAWI_", "SRAW" , "SRAW_" , "RLDCL" , "RLDCL_" , "RLDCR" , "RLDCR_" , "RLDIMI", "RLDIMI_",
"SLW" , "SLW_" , "SLD" , "SLD_" ,
"SRW" , "SRW_" , "SRAWI" , "SRAWI_" , "SRAW" , "SRAW_" ,
"SRD" , "SRD_" , "SRADI" , "SRADI_" , "SRAD" , "SRAD_" ,
] ]




@ -16,11 +19,31 @@ class RLWNM (InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.RLWNM ): pass
class RLWNM_ (InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.RLWNM_ ): pass class RLWNM_ (InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.RLWNM_ ): pass
class RLWIMI (InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.RLWIMI ): pass class RLWIMI (InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.RLWIMI ): pass
class RLWIMI_(InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.RLWIMI_): pass class RLWIMI_(InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.RLWIMI_): pass
class RLDICL (InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.RLDICL ): pass
class RLDICL_(InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.RLDICL_): pass
class RLDICR (InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.RLDICR ): pass
class RLDICR_(InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.RLDICR_): pass
class RLDIC (InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.RLDIC ): pass
class RLDIC_ (InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.RLDIC_ ): pass
class RLDCL (InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.RLDCL ): pass
class RLDCL_ (InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.RLDCL_ ): pass
class RLDCR (InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.RLDCR ): pass
class RLDCR_ (InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.RLDCR_ ): pass
class RLDIMI (InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.RLDIMI ): pass
class RLDIMI_(InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.RLDIMI_): pass
class SLW (InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.SLW ): pass class SLW (InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.SLW ): pass
class SLW_ (InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.SLW_ ): pass class SLW_ (InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.SLW_ ): pass
class SLD (InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.SLD ): pass
class SLD_ (InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.SLD_ ): pass
class SRW (InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.SRW ): pass class SRW (InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.SRW ): pass
class SRW_ (InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.SRW_ ): pass class SRW_ (InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.SRW_ ): pass
class SRAWI (InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.SRAWI ): pass class SRAWI (InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.SRAWI ): pass
class SRAWI_ (InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.SRAWI_ ): pass class SRAWI_ (InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.SRAWI_ ): pass
class SRAW (InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.SRAW ): pass class SRAW (InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.SRAW ): pass
class SRAW_ (InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.SRAW_ ): pass class SRAW_ (InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.SRAW_ ): pass
class SRD (InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.SRD ): pass
class SRD_ (InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.SRD_ ): pass
class SRADI (InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.SRADI ): pass
class SRADI_ (InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.SRADI_ ): pass
class SRAD (InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.SRAD ): pass
class SRAD_ (InsnCheck, spec_cls=RotateShiftSpec, insn_cls=const.SRAD_ ): pass

@ -236,6 +236,19 @@ class RLWNM_ (WordInsn): _fields = (f.PO(23), f.RS(), f.RA(), f.RB(), f.MB(), f
class RLWIMI (WordInsn): _fields = (f.PO(20), f.RS(), f.RA(), f.SH(), f.MB(), f.ME(), f.Rc(0)) class RLWIMI (WordInsn): _fields = (f.PO(20), f.RS(), f.RA(), f.SH(), f.MB(), f.ME(), f.Rc(0))
class RLWIMI_ (WordInsn): _fields = (f.PO(20), f.RS(), f.RA(), f.SH(), f.MB(), f.ME(), f.Rc(1)) class RLWIMI_ (WordInsn): _fields = (f.PO(20), f.RS(), f.RA(), f.SH(), f.MB(), f.ME(), f.Rc(1))


class RLDICL (WordInsn): _fields = (f.PO(30), f.RS(), f.RA(), f.sh1(), f.mb0(), f.mb1(), f.XO_MD(0), f.sh0(), f.Rc(0))
class RLDICL_ (WordInsn): _fields = (f.PO(30), f.RS(), f.RA(), f.sh1(), f.mb0(), f.mb1(), f.XO_MD(0), f.sh0(), f.Rc(1))
class RLDICR (WordInsn): _fields = (f.PO(30), f.RS(), f.RA(), f.sh1(), f.me0(), f.me1(), f.XO_MD(1), f.sh0(), f.Rc(0))
class RLDICR_ (WordInsn): _fields = (f.PO(30), f.RS(), f.RA(), f.sh1(), f.me0(), f.me1(), f.XO_MD(1), f.sh0(), f.Rc(1))
class RLDIC (WordInsn): _fields = (f.PO(30), f.RS(), f.RA(), f.sh1(), f.mb0(), f.mb1(), f.XO_MD(2), f.sh0(), f.Rc(0))
class RLDIC_ (WordInsn): _fields = (f.PO(30), f.RS(), f.RA(), f.sh1(), f.mb0(), f.mb1(), f.XO_MD(2), f.sh0(), f.Rc(1))
class RLDCL (WordInsn): _fields = (f.PO(30), f.RS(), f.RA(), f.RB(), f.mb0(), f.mb1(), f.XO_MDS(8), f.Rc(0))
class RLDCL_ (WordInsn): _fields = (f.PO(30), f.RS(), f.RA(), f.RB(), f.mb0(), f.mb1(), f.XO_MDS(8), f.Rc(1))
class RLDCR (WordInsn): _fields = (f.PO(30), f.RS(), f.RA(), f.RB(), f.me0(), f.me1(), f.XO_MDS(9), f.Rc(0))
class RLDCR_ (WordInsn): _fields = (f.PO(30), f.RS(), f.RA(), f.RB(), f.me0(), f.me1(), f.XO_MDS(9), f.Rc(1))
class RLDIMI (WordInsn): _fields = (f.PO(30), f.RS(), f.RA(), f.sh1(), f.mb0(), f.mb1(), f.XO_MD(3), f.sh0(), f.Rc(0))
class RLDIMI_ (WordInsn): _fields = (f.PO(30), f.RS(), f.RA(), f.sh1(), f.mb0(), f.mb1(), f.XO_MD(3), f.sh0(), f.Rc(1))

class SLW (WordInsn): _fields = (f.PO(31), f.RS(), f.RA(), f.RB(), f.XO_X( 24), f.Rc(0)) class SLW (WordInsn): _fields = (f.PO(31), f.RS(), f.RA(), f.RB(), f.XO_X( 24), f.Rc(0))
class SLW_ (WordInsn): _fields = (f.PO(31), f.RS(), f.RA(), f.RB(), f.XO_X( 24), f.Rc(1)) class SLW_ (WordInsn): _fields = (f.PO(31), f.RS(), f.RA(), f.RB(), f.XO_X( 24), f.Rc(1))
class SRW (WordInsn): _fields = (f.PO(31), f.RS(), f.RA(), f.RB(), f.XO_X(536), f.Rc(0)) class SRW (WordInsn): _fields = (f.PO(31), f.RS(), f.RA(), f.RB(), f.XO_X(536), f.Rc(0))
@ -245,6 +258,15 @@ class SRAWI_ (WordInsn): _fields = (f.PO(31), f.RS(), f.RA(), f.SH(), f.XO_X(82
class SRAW (WordInsn): _fields = (f.PO(31), f.RS(), f.RA(), f.RB(), f.XO_X(792), f.Rc(0)) class SRAW (WordInsn): _fields = (f.PO(31), f.RS(), f.RA(), f.RB(), f.XO_X(792), f.Rc(0))
class SRAW_ (WordInsn): _fields = (f.PO(31), f.RS(), f.RA(), f.RB(), f.XO_X(792), f.Rc(1)) class SRAW_ (WordInsn): _fields = (f.PO(31), f.RS(), f.RA(), f.RB(), f.XO_X(792), f.Rc(1))


class SLD (WordInsn): _fields = (f.PO(31), f.RS(), f.RA(), f.RB(), f.XO_X( 27), f.Rc(0))
class SLD_ (WordInsn): _fields = (f.PO(31), f.RS(), f.RA(), f.RB(), f.XO_X( 27), f.Rc(1))
class SRD (WordInsn): _fields = (f.PO(31), f.RS(), f.RA(), f.RB(), f.XO_X(539), f.Rc(0))
class SRD_ (WordInsn): _fields = (f.PO(31), f.RS(), f.RA(), f.RB(), f.XO_X(539), f.Rc(1))
class SRADI (WordInsn): _fields = (f.PO(31), f.RS(), f.RA(), f.sh1(), f.XO_XS(413), f.sh0(), f.Rc(0))
class SRADI_ (WordInsn): _fields = (f.PO(31), f.RS(), f.RA(), f.sh1(), f.XO_XS(413), f.sh0(), f.Rc(1))
class SRAD (WordInsn): _fields = (f.PO(31), f.RS(), f.RA(), f.RB(), f.XO_X(794), f.Rc(0))
class SRAD_ (WordInsn): _fields = (f.PO(31), f.RS(), f.RA(), f.RB(), f.XO_X(794), f.Rc(1))

# BCD Assist # BCD Assist


class CDTBCD (WordInsn): _fields = (f.PO(31), f.RS(), f.RA(), f.XO_X(282)) class CDTBCD (WordInsn): _fields = (f.PO(31), f.RS(), f.RA(), f.XO_X(282))

@ -28,7 +28,11 @@ class LK (InsnField): _shape = unsigned( 1); _offset = 31; _name = "LK"
class OE (InsnField): _shape = unsigned( 1); _offset = 21; _name = "OE" class OE (InsnField): _shape = unsigned( 1); _offset = 21; _name = "OE"
class PO (InsnField): _shape = unsigned( 6); _offset = 0; _name = "PO" class PO (InsnField): _shape = unsigned( 6); _offset = 0; _name = "PO"
class MB (InsnField): _shape = unsigned( 5); _offset = 21; _name = "MB" class MB (InsnField): _shape = unsigned( 5); _offset = 21; _name = "MB"
class mb0 (InsnField): _shape = unsigned( 1); _offset = 26; _name = "mb0"
class mb1 (InsnField): _shape = unsigned( 5); _offset = 21; _name = "mb1"
class ME (InsnField): _shape = unsigned( 5); _offset = 26; _name = "ME" class ME (InsnField): _shape = unsigned( 5); _offset = 26; _name = "ME"
class me0 (InsnField): _shape = unsigned( 1); _offset = 26; _name = "me0"
class me1 (InsnField): _shape = unsigned( 5); _offset = 21; _name = "me1"
class RA (InsnField): _shape = unsigned( 5); _offset = 11; _name = "RA" class RA (InsnField): _shape = unsigned( 5); _offset = 11; _name = "RA"
class RB (InsnField): _shape = unsigned( 5); _offset = 16; _name = "RB" class RB (InsnField): _shape = unsigned( 5); _offset = 16; _name = "RB"
class Rc (InsnField): _shape = unsigned( 1); _offset = 31; _name = "Rc" class Rc (InsnField): _shape = unsigned( 1); _offset = 31; _name = "Rc"
@ -38,6 +42,8 @@ class SC_30 (InsnField): _shape = unsigned( 1); _offset = 30; _name = "_30"
class SC_31 (InsnField): _shape = unsigned( 1); _offset = 31; _name = "_31" class SC_31 (InsnField): _shape = unsigned( 1); _offset = 31; _name = "_31"
class SI (InsnField): _shape = signed(16); _offset = 16; _name = "SI" class SI (InsnField): _shape = signed(16); _offset = 16; _name = "SI"
class SH (InsnField): _shape = unsigned( 5); _offset = 16; _name = "SH" class SH (InsnField): _shape = unsigned( 5); _offset = 16; _name = "SH"
class sh0 (InsnField): _shape = unsigned( 1); _offset = 30; _name = "sh0"
class sh1 (InsnField): _shape = unsigned( 5); _offset = 16; _name = "sh1"
class TO (InsnField): _shape = unsigned( 5); _offset = 6; _name = "TO" class TO (InsnField): _shape = unsigned( 5); _offset = 6; _name = "TO"
class UI (InsnField): _shape = unsigned(16); _offset = 16; _name = "UI" class UI (InsnField): _shape = unsigned(16); _offset = 16; _name = "UI"
class XFX_11(InsnField): _shape = unsigned( 1); _offset = 11; _name = "_11" class XFX_11(InsnField): _shape = unsigned( 1); _offset = 11; _name = "_11"
@ -47,6 +53,9 @@ class XO_X (InsnField): _shape = unsigned(10); _offset = 21; _name = "XO"
class XO_XFX(InsnField): _shape = unsigned(10); _offset = 21; _name = "XO" class XO_XFX(InsnField): _shape = unsigned(10); _offset = 21; _name = "XO"
class XO_XL (InsnField): _shape = unsigned(10); _offset = 21; _name = "XO" class XO_XL (InsnField): _shape = unsigned(10); _offset = 21; _name = "XO"
class XO_Z23(InsnField): _shape = unsigned( 8); _offset = 23; _name = "XO" class XO_Z23(InsnField): _shape = unsigned( 8); _offset = 23; _name = "XO"
class XO_MD (InsnField): _shape = unsigned( 3); _offset = 27; _name = "XO"
class XO_MDS(InsnField): _shape = unsigned( 4); _offset = 27; _name = "XO"
class XO_XS (InsnField): _shape = unsigned( 9); _offset = 21; _name = "XO"




class SPR(InsnField): class SPR(InsnField):

@ -199,35 +199,35 @@ class LoadStoreSpec(InsnSpec, Elaboratable):
load_result = Signal(64) load_result = Signal(64)


m.d.comb += [ m.d.comb += [
load_byte.eq(self.pfv.mem.r_data.word_select(byte_offset, width= 8)), load_byte.eq(self.pfv.mem.r_data.word_select(7 - byte_offset, width= 8)),
load_half.eq(self.pfv.mem.r_data.word_select(half_offset, width=16)), load_half.eq(self.pfv.mem.r_data.word_select(3 - half_offset, width=16)),
load_word.eq(self.pfv.mem.r_data.word_select(word_offset, width=32)), load_word.eq(self.pfv.mem.r_data.word_select(1 - word_offset, width=32)),
] ]


if isinstance(self.insn, (LBZ, LBZX, LBZU, LBZUX)): if isinstance(self.insn, (LBZ, LBZX, LBZU, LBZUX)):
m.d.comb += [ m.d.comb += [
self.pfv.mem.r_mask.word_select(byte_offset, width=1).eq(0x1), self.pfv.mem.r_mask.word_select(7 - byte_offset, width=1).eq(0x1),
load_result.eq(load_byte.as_unsigned()), load_result.eq(load_byte.as_unsigned()),
] ]
elif isinstance(self.insn, (LHZ, LHZX, LHZU, LHZUX)): elif isinstance(self.insn, (LHZ, LHZX, LHZU, LHZUX)):
m.d.comb += [ m.d.comb += [
self.pfv.mem.r_mask.word_select(half_offset, width=2).eq(0x3), self.pfv.mem.r_mask.word_select(3 - half_offset, width=2).eq(0x3),
load_result.eq(byte_reversed(load_half, ~msr_le).as_unsigned()), load_result.eq(byte_reversed(load_half, msr_le).as_unsigned()),
] ]
elif isinstance(self.insn, (LHA, LHAX, LHAU, LHAUX)): elif isinstance(self.insn, (LHA, LHAX, LHAU, LHAUX)):
m.d.comb += [ m.d.comb += [
self.pfv.mem.r_mask.word_select(half_offset, width=2).eq(0x3), self.pfv.mem.r_mask.word_select(3 - half_offset, width=2).eq(0x3),
load_result.eq(byte_reversed(load_half, ~msr_le).as_signed()) load_result.eq(byte_reversed(load_half, msr_le).as_signed())
] ]
elif isinstance(self.insn, (LWZ, LWZX, LWZU, LWZUX)): elif isinstance(self.insn, (LWZ, LWZX, LWZU, LWZUX)):
m.d.comb += [ m.d.comb += [
self.pfv.mem.r_mask.word_select(word_offset, width=4).eq(0xf), self.pfv.mem.r_mask.word_select(1 - word_offset, width=4).eq(0xf),
load_result.eq(byte_reversed(load_word, ~msr_le).as_unsigned()), load_result.eq(byte_reversed(load_word, msr_le).as_unsigned()),
] ]
elif isinstance(self.insn, LWBRX): elif isinstance(self.insn, LWBRX):
m.d.comb += [ m.d.comb += [
self.pfv.mem.r_mask.word_select(word_offset, width=4).eq(0xf), self.pfv.mem.r_mask.word_select(1 - word_offset, width=4).eq(0xf),
load_result.eq(byte_reversed(load_word, msr_le).as_unsigned()), load_result.eq(byte_reversed(load_word, ~msr_le).as_unsigned()),
] ]
else: else:
assert False assert False
@ -261,28 +261,28 @@ class LoadStoreSpec(InsnSpec, Elaboratable):


if isinstance(self.insn, (STB, STBX, STBU, STBUX)): if isinstance(self.insn, (STB, STBX, STBU, STBUX)):
m.d.comb += [ m.d.comb += [
self.pfv.mem.w_mask.word_select(byte_offset, width=1).eq(0x1), self.pfv.mem.w_mask.word_select(7 - byte_offset, width=1).eq(0x1),
self.pfv.mem.w_data.eq(store_byte), self.pfv.mem.w_data.eq(store_byte),
] ]
elif isinstance(self.insn, (STH, STHX, STHU, STHUX)): elif isinstance(self.insn, (STH, STHX, STHU, STHUX)):
m.d.comb += [ m.d.comb += [
self.pfv.mem.w_mask.word_select(half_offset, width=2).eq(0x3), self.pfv.mem.w_mask.word_select(3 - half_offset, width=2).eq(0x3),
self.pfv.mem.w_data.eq(byte_reversed(store_half, ~msr_le)), self.pfv.mem.w_data.eq(byte_reversed(store_half, msr_le)),
] ]
elif isinstance(self.insn, (STW, STWX, STWU, STWUX)): elif isinstance(self.insn, (STW, STWX, STWU, STWUX)):
m.d.comb += [ m.d.comb += [
self.pfv.mem.w_mask.word_select(word_offset, width=4).eq(0xf), self.pfv.mem.w_mask.word_select(1 - word_offset, width=4).eq(0xf),
self.pfv.mem.w_data.eq(byte_reversed(store_word, ~msr_le)), self.pfv.mem.w_data.eq(byte_reversed(store_word, msr_le)),
] ]
elif isinstance(self.insn, STHBRX): elif isinstance(self.insn, STHBRX):
m.d.comb += [ m.d.comb += [
self.pfv.mem.w_mask.word_select(half_offset, width=2).eq(0x3), self.pfv.mem.w_mask.word_select(3 - half_offset, width=2).eq(0x3),
self.pfv.mem.w_data.eq(byte_reversed(store_half, msr_le)), self.pfv.mem.w_data.eq(byte_reversed(store_half, ~msr_le)),
] ]
elif isinstance(self.insn, STWBRX): elif isinstance(self.insn, STWBRX):
m.d.comb += [ m.d.comb += [
self.pfv.mem.w_mask.word_select(word_offset, width=4).eq(0xf), self.pfv.mem.w_mask.word_select(1 - word_offset, width=4).eq(0xf),
self.pfv.mem.w_data.eq(byte_reversed(store_word, msr_le)), self.pfv.mem.w_data.eq(byte_reversed(store_word, ~msr_le)),
] ]
else: else:
assert False assert False

@ -58,29 +58,51 @@ class RotateShiftSpec(InsnSpec, Elaboratable):


with m.Else(): with m.Else():
src = Signal(unsigned(64)) src = Signal(unsigned(64))
shamt = Signal(unsigned( 6)) shamt = Signal(unsigned( 7))
rotl = Signal(unsigned(64)) rotl = Signal(unsigned(64))
mask = Signal(unsigned(64)) mask = Signal(unsigned(64))
result = Signal(unsigned(64)) result = Signal(unsigned(64))


# Source operand : (RS)(32:63)||(RS)(32:63) # Source operand : (RS)(32:63)||(RS)(32:63) or (RS)


m.d.comb += [ if isinstance(self.insn, (RLWINM, RLWINM_, RLWNM, RLWNM_, RLWIMI, RLWIMI_,
self.pfv.rs.index.eq(self.insn.RS), SLW, SLW_, SRW, SRW_, SRAWI, SRAWI_, SRAW, SRAW_)):
self.pfv.rs.r_stb.eq(1), m.d.comb += [
src.eq(self.pfv.rs.r_data), self.pfv.rs.index.eq(self.insn.RS),
] self.pfv.rs.r_stb.eq(1),
src.eq(Cat(self.pfv.rs.r_data[:32], self.pfv.rs.r_data[:32])),
]
elif isinstance(self.insn, (RLDICL, RLDICL_, RLDICR, RLDICR_, RLDIC, RLDIC_,
RLDCL, RLDCL_, RLDCR, RLDCR_, RLDIMI, RLDIMI_,
SLD, SLD_, SRD, SRD_, SRADI, SRADI_, SRAD, SRAD_)):
m.d.comb += [
self.pfv.rs.index.eq(self.insn.RS),
self.pfv.rs.r_stb.eq(1),
src.eq(self.pfv.rs.r_data),
]
else:
assert False


# Shift amount : SH or (RB)(59:63) # Shift amount : SH or (RB)(59:63) or (RB)(58:63)


if isinstance(self.insn, (RLWINM, RLWINM_, RLWIMI, RLWIMI_, SRAWI, SRAWI_)): if isinstance(self.insn, (RLWINM, RLWINM_, RLWIMI, RLWIMI_, SRAWI, SRAWI_)):
m.d.comb += shamt.eq(self.insn.SH) m.d.comb += shamt.eq(self.insn.SH)
elif isinstance(self.insn, (RLDICL, RLDICL_, RLDICR, RLDICR_, RLDIC, RLDIC_,
RLDIMI, RLDIMI_, SRADI, SRADI_)):
m.d.comb += shamt.eq(Cat(self.insn.sh1, self.insn.sh0))
elif isinstance(self.insn, (RLWNM, RLWNM_, SLW, SLW_, SRW, SRW_, SRAW, SRAW_)): elif isinstance(self.insn, (RLWNM, RLWNM_, SLW, SLW_, SRW, SRW_, SRAW, SRAW_)):
m.d.comb += [ m.d.comb += [
self.pfv.rb.index.eq(self.insn.RB), self.pfv.rb.index.eq(self.insn.RB),
self.pfv.rb.r_stb.eq(1), self.pfv.rb.r_stb.eq(1),
shamt.eq(self.pfv.rb.r_data[:6]), shamt.eq(self.pfv.rb.r_data[:6]),
] ]
elif isinstance(self.insn, (RLDCL, RLDCL_, RLDCR, RLDCR_, SLD, SLD_, SRD, SRD_,
SRAD, SRAD_)):
m.d.comb += [
self.pfv.rb.index.eq(self.insn.RB),
self.pfv.rb.r_stb.eq(1),
shamt.eq(self.pfv.rb.r_data[:7]),
]
else: else:
assert False assert False


@ -93,28 +115,43 @@ class RotateShiftSpec(InsnSpec, Elaboratable):


if isinstance(self.insn, (RLWINM, RLWINM_, RLWNM, RLWNM_, RLWIMI, RLWIMI_)): if isinstance(self.insn, (RLWINM, RLWINM_, RLWNM, RLWNM_, RLWIMI, RLWIMI_)):
m.d.comb += mask.eq(_mask(self.insn.MB+32, self.insn.ME+32)) m.d.comb += mask.eq(_mask(self.insn.MB+32, self.insn.ME+32))
elif isinstance(self.insn, (RLDICL, RLDICL_, RLDCL, RLDCL_)):
m.d.comb += mask.eq(_mask(Cat(self.insn.mb1, self.insn.mb0), 63))
elif isinstance(self.insn, (RLDICR, RLDICR_, RLDCR, RLDCR_)):
m.d.comb += mask.eq(_mask(0, Cat(self.insn.me1, self.insn.me0)))
elif isinstance(self.insn, (RLDIC, RLDIC_, RLDIMI, RLDIMI_)):
m.d.comb += mask.eq(_mask(Cat(self.insn.mb1, self.insn.mb0), 63-shamt))
elif isinstance(self.insn, (SLW, SLW_)): elif isinstance(self.insn, (SLW, SLW_)):
m.d.comb += mask.eq(Mux(shamt[5], 0, _mask(32, 63-shamt))) m.d.comb += mask.eq(Mux(shamt[5], 0, _mask(32, 63-shamt)))
elif isinstance(self.insn, (SRW, SRW_, SRAW, SRAW_)): elif isinstance(self.insn, (SRW, SRW_, SRAW, SRAW_)):
m.d.comb += mask.eq(Mux(shamt[5], 0, _mask(shamt+32, 63))) m.d.comb += mask.eq(Mux(shamt[5], 0, _mask(shamt+32, 63)))
elif isinstance(self.insn, (SRAWI, SRAWI_)): elif isinstance(self.insn, (SRAWI, SRAWI_)):
m.d.comb += mask.eq(_mask(shamt+32, 63)) m.d.comb += mask.eq(_mask(shamt+32, 63))
elif isinstance(self.insn, (SLD, SLD_)):
m.d.comb += mask.eq(Mux(shamt[6], 0, _mask(0, 63-shamt)))
elif isinstance(self.insn, (SRD, SRD_, SRAD, SRAD_)):
m.d.comb += mask.eq(Mux(shamt[6], 0, _mask(shamt, 63)))
elif isinstance(self.insn, (SRADI, SRADI_)):
m.d.comb += mask.eq(_mask(shamt, 63))
else: else:
assert False assert False


# Rotation # Rotation


def _rotl32(src, n): def _rotl(src, n):
v = Repl(src[:32], 2) return ((src << n) | (src >> 64-n)) & Repl(1, 64)
return ((v << n) | (v >> 64-n)) & Repl(1, 64)


if isinstance(self.insn, ( if isinstance(self.insn, (RLWINM, RLWINM_, RLWNM, RLWNM_, RLWIMI, RLWIMI_,
RLWINM, RLWINM_, RLWNM, RLWNM_, RLWIMI, RLWIMI_, SLW, SLW_)):
SLW, SLW_, m.d.comb += rotl.eq(_rotl(src, shamt[:5]))
)): elif isinstance(self.insn, (RLDICL, RLDICL_, RLDICR, RLDICR_, RLDIC, RLDIC_,
m.d.comb += rotl.eq(_rotl32(src, shamt)) RLDCL, RLDCL_, RLDCR, RLDCR_, RLDIMI, RLDIMI_,
SLD, SLD_)):
m.d.comb += rotl.eq(_rotl(src, shamt[:6]))
elif isinstance(self.insn, (SRW, SRW_, SRAWI, SRAWI_, SRAW, SRAW_)): elif isinstance(self.insn, (SRW, SRW_, SRAWI, SRAWI_, SRAW, SRAW_)):
m.d.comb += rotl.eq(_rotl32(src, 64-shamt)) m.d.comb += rotl.eq(_rotl(src, 64-shamt[:5]))
elif isinstance(self.insn, (SRD, SRD_, SRADI, SRADI_, SRAD, SRAD_)):
m.d.comb += rotl.eq(_rotl(src, 64-shamt[:6]))
else: else:
assert False assert False


@ -126,21 +163,25 @@ class RotateShiftSpec(InsnSpec, Elaboratable):
self.pfv.ra.w_data.eq(result), self.pfv.ra.w_data.eq(result),
] ]


if isinstance(self.insn, (RLWINM, RLWINM_, RLWNM, RLWNM_, SLW, SLW_, SRW, SRW_)): if isinstance(self.insn, (RLWINM, RLWINM_, RLWNM, RLWNM_, RLDICL, RLDICL_,
RLDICR, RLDICR_, RLDIC, RLDIC_, RLDCL, RLDCL_,
RLDCR, RLDCR_, SLW, SLW_, SRW, SRW_, SLD, SLD_, SRD, SRD_)):
m.d.comb += result.eq(rotl & mask) m.d.comb += result.eq(rotl & mask)
elif isinstance(self.insn, (RLWIMI, RLWIMI_)): elif isinstance(self.insn, (RLWIMI, RLWIMI_, RLDIMI, RLDIMI_)):
m.d.comb += self.pfv.ra.r_stb.eq(1) m.d.comb += self.pfv.ra.r_stb.eq(1)
m.d.comb += result.eq(rotl & mask | self.pfv.ra.r_data & ~mask) m.d.comb += result.eq(rotl & mask | self.pfv.ra.r_data & ~mask)
elif isinstance(self.insn, (SRAWI, SRAWI_, SRAW, SRAW_)): elif isinstance(self.insn, (SRAWI, SRAWI_, SRAW, SRAW_)):
m.d.comb += result.eq(rotl & mask | Repl(src[31], 64) & ~mask) m.d.comb += result.eq(rotl & mask | Repl(src[31], 64) & ~mask)
elif isinstance(self.insn, (SRADI, SRADI_, SRAD, SRAD_)):
m.d.comb += result.eq(rotl & mask | Repl(src[63], 64) & ~mask)
else: else:
assert False assert False


# Write CR0 # Write CR0


if isinstance(self.insn, ( if isinstance(self.insn, (
RLWINM_, RLWNM_, RLWIMI_, SLW_, SRW_, SRAWI_, SRAW_, RLWINM_, RLWNM_, RLWIMI_, RLDICL_, RLDICR_, RLDIC_, RLDCL_, RLDCR_, RLDIMI_,
)): SLW_, SRW_, SRAWI_, SRAW_, SLD_, SRD_, SRADI_, SRAD_)):
cr0_w_mask = Record([("so", 1), ("eq_", 1), ("gt", 1), ("lt", 1)]) cr0_w_mask = Record([("so", 1), ("eq_", 1), ("gt", 1), ("lt", 1)])
cr0_w_data = Record([("so", 1), ("eq_", 1), ("gt", 1), ("lt", 1)]) cr0_w_data = Record([("so", 1), ("eq_", 1), ("gt", 1), ("lt", 1)])


@ -163,7 +204,18 @@ class RotateShiftSpec(InsnSpec, Elaboratable):
carry = Signal() carry = Signal()


m.d.comb += [ m.d.comb += [
carry.eq(src[31] & (rotl & ~mask)[:32].any()), carry.eq(Mux(shamt[5], 0, src[31] & (rotl & ~mask)[:32].any())),

self.pfv.xer.w_mask.ca .eq(1),
self.pfv.xer.w_data.ca .eq(carry),
self.pfv.xer.w_mask.ca32.eq(1),
self.pfv.xer.w_data.ca32.eq(carry),
]
elif isinstance(self.insn, (SRADI, SRADI_, SRAD, SRAD_)):
carry = Signal()

m.d.comb += [
carry.eq(Mux(shamt[6], 0, src[63] & (rotl & ~mask).any())),


self.pfv.xer.w_mask.ca .eq(1), self.pfv.xer.w_mask.ca .eq(1),
self.pfv.xer.w_data.ca .eq(carry), self.pfv.xer.w_data.ca .eq(carry),

Loading…
Cancel
Save