+ # only when Rc=0
+ comb += self.RC1.eq(mode[SVP64MODE.RC1])
+ with m.If(~is_ldst):
+ comb += self.vli.eq(mode[SVP64MODE.VLI])
+ comb += self.cr_sel.eq(0b10) # EQ bit index is implicit
+
+ # extract saturate
+ with m.Switch(mode2):
+ with m.Case(2):
+ with m.If(mode[SVP64MODE.N]):
+ comb += self.saturate.eq(SVP64Sat.UNSIGNED)
+ with m.Else():
+ comb += self.saturate.eq(SVP64Sat.SIGNED)
+ with m.Default():
+ comb += self.saturate.eq(SVP64Sat.NONE)
+
+ # do elwidth/elwidth_src extract
+ comb += self.ew_src.eq(self.rm_in.ewsrc)
+ comb += self.ew_dst.eq(self.rm_in.elwidth)
+ comb += self.subvl.eq(self.rm_in.subvl)
+
+ # extract els (element strided mode bit)
+ # see https://libre-soc.org/openpower/sv/ldst/
+ els = Signal()
+ with m.Switch(mode2):
+ with m.Case(0, 2):
+ comb += els.eq(mode[SVP64MODE.LDST_ELS])
+ with m.Case(1, 3):
+ with m.If(self.rc_in):
+ comb += els.eq(mode[SVP64MODE.ELS_FFIRST_PRED])
+
+ # RA is vectorised
+ with m.If(self.ldst_ra_vec):
+ comb += self.ldstmode.eq(SVP64LDSTmode.INDEXED)
+ # not element-strided, therefore unit...
+ with m.Elif(~els):
+ comb += self.ldstmode.eq(SVP64LDSTmode.UNITSTRIDE)
+ # but if the LD/ST immediate is zero, allow cache-inhibited
+ # loads from same location, therefore don't do element-striding
+ with m.Elif(~self.ldst_imz_in):
+ comb += self.ldstmode.eq(SVP64LDSTmode.ELSTRIDE)
+
+ ######################
+ # arith decoding
+ ######################
+ with m.Else():
+ with m.Switch(mode2):
+ with m.Case(0): # needs further decoding (LDST no mapreduce)
+ with m.If(mode[SVP64MODE.REDUCE]):
+ comb += self.mode.eq(SVP64RMMode.MAPREDUCE)
+ with m.Else():
+ comb += self.mode.eq(SVP64RMMode.NORMAL)
+ with m.Case(1,3):
+ comb += self.mode.eq(SVP64RMMode.FFIRST) # ffirst
+ with m.Case(2):
+ comb += self.mode.eq(SVP64RMMode.SATURATE) # saturate
+
+ # extract "reverse gear" for mapreduce mode
+ with m.If((~is_ldst) & # not for LD/ST
+ (mode2 == 0) & # first 2 bits == 0
+ mode[SVP64MODE.REDUCE] & # bit 2 == 1
+ (~mode[SVP64MODE.MOD3])): # bit 3 == 0
+ comb += self.reverse_gear.eq(mode[SVP64MODE.RG]) # finally whew
+
+ # extract zeroing
+ with m.Switch(mode2):
+ with m.Case(0):
+ # normal-mode only active in simple mode
+ with m.If(~mode[SVP64MODE.REDUCE]): # bit 2 is zero?
+ comb += self.pred_sz.eq(mode[SVP64MODE.SZ])