|
|
|
@ -58,29 +58,51 @@ class RotateShiftSpec(InsnSpec, Elaboratable):
|
|
|
|
|
|
|
|
|
|
with m.Else():
|
|
|
|
|
src = Signal(unsigned(64))
|
|
|
|
|
shamt = Signal(unsigned( 6))
|
|
|
|
|
shamt = Signal(unsigned( 7))
|
|
|
|
|
rotl = Signal(unsigned(64))
|
|
|
|
|
mask = 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 += [
|
|
|
|
|
self.pfv.rs.index.eq(self.insn.RS),
|
|
|
|
|
self.pfv.rs.r_stb.eq(1),
|
|
|
|
|
src.eq(self.pfv.rs.r_data),
|
|
|
|
|
]
|
|
|
|
|
if isinstance(self.insn, (RLWINM, RLWINM_, RLWNM, RLWNM_, RLWIMI, RLWIMI_,
|
|
|
|
|
SLW, SLW_, SRW, SRW_, SRAWI, SRAWI_, SRAW, SRAW_)):
|
|
|
|
|
m.d.comb += [
|
|
|
|
|
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_)):
|
|
|
|
|
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_)):
|
|
|
|
|
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[: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:
|
|
|
|
|
assert False
|
|
|
|
|
|
|
|
|
@ -93,28 +115,43 @@ class RotateShiftSpec(InsnSpec, Elaboratable):
|
|
|
|
|
|
|
|
|
|
if isinstance(self.insn, (RLWINM, RLWINM_, RLWNM, RLWNM_, RLWIMI, RLWIMI_)):
|
|
|
|
|
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_)):
|
|
|
|
|
m.d.comb += mask.eq(Mux(shamt[5], 0, _mask(32, 63-shamt)))
|
|
|
|
|
elif isinstance(self.insn, (SRW, SRW_, SRAW, SRAW_)):
|
|
|
|
|
m.d.comb += mask.eq(Mux(shamt[5], 0, _mask(shamt+32, 63)))
|
|
|
|
|
elif isinstance(self.insn, (SRAWI, SRAWI_)):
|
|
|
|
|
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:
|
|
|
|
|
assert False
|
|
|
|
|
|
|
|
|
|
# Rotation
|
|
|
|
|
|
|
|
|
|
def _rotl32(src, n):
|
|
|
|
|
v = Repl(src[:32], 2)
|
|
|
|
|
return ((v << n) | (v >> 64-n)) & Repl(1, 64)
|
|
|
|
|
def _rotl(src, n):
|
|
|
|
|
return ((src << n) | (src >> 64-n)) & Repl(1, 64)
|
|
|
|
|
|
|
|
|
|
if isinstance(self.insn, (
|
|
|
|
|
RLWINM, RLWINM_, RLWNM, RLWNM_, RLWIMI, RLWIMI_,
|
|
|
|
|
SLW, SLW_,
|
|
|
|
|
)):
|
|
|
|
|
m.d.comb += rotl.eq(_rotl32(src, shamt))
|
|
|
|
|
if isinstance(self.insn, (RLWINM, RLWINM_, RLWNM, RLWNM_, RLWIMI, RLWIMI_,
|
|
|
|
|
SLW, SLW_)):
|
|
|
|
|
m.d.comb += rotl.eq(_rotl(src, shamt[:5]))
|
|
|
|
|
elif isinstance(self.insn, (RLDICL, RLDICL_, RLDICR, RLDICR_, RLDIC, RLDIC_,
|
|
|
|
|
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_)):
|
|
|
|
|
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:
|
|
|
|
|
assert False
|
|
|
|
|
|
|
|
|
@ -126,21 +163,25 @@ class RotateShiftSpec(InsnSpec, Elaboratable):
|
|
|
|
|
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)
|
|
|
|
|
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 += result.eq(rotl & mask | self.pfv.ra.r_data & ~mask)
|
|
|
|
|
elif isinstance(self.insn, (SRAWI, SRAWI_, SRAW, SRAW_)):
|
|
|
|
|
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:
|
|
|
|
|
assert False
|
|
|
|
|
|
|
|
|
|
# Write CR0
|
|
|
|
|
|
|
|
|
|
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_data = Record([("so", 1), ("eq_", 1), ("gt", 1), ("lt", 1)])
|
|
|
|
|
|
|
|
|
@ -163,7 +204,18 @@ class RotateShiftSpec(InsnSpec, Elaboratable):
|
|
|
|
|
carry = Signal()
|
|
|
|
|
|
|
|
|
|
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_data.ca .eq(carry),
|
|
|
|
|