From ee73b7c26c866d2a98f42196403bf513593dd91a Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Sun, 21 May 2023 15:23:19 +0100 Subject: [PATCH] big set of updates to LD/ST in line with new spec changes https://bugs.libre-soc.org/show_bug.cgi?id=1083 LD/ST-imm and LD/ST-idx are now pretty similar --- src/openpower/consts.py | 8 +-- src/openpower/decoder/power_insn.py | 41 +++--------- src/openpower/decoder/power_svp64_rm.py | 84 +++++-------------------- 3 files changed, 25 insertions(+), 108 deletions(-) diff --git a/src/openpower/consts.py b/src/openpower/consts.py index 9774eda3..dd09c8b8 100644 --- a/src/openpower/consts.py +++ b/src/openpower/consts.py @@ -268,12 +268,10 @@ class SVP64MODEb(_Const): # LD immediate els (element-stride) locations, depending on mode ELS_NORMAL = 4 ELS_FFIRST_PRED = 3 - ELS_SAT = 4 - LDI_POST = 2 # LD-Immediate Post/FF Mode - LDI_PI = 3 # LD-Immediate Post-Increment + LDI_PI = 2 # LD-Immediate Post-Increment LDI_FF = 4 # LD-Immediate Fault-First - # LDST Indexed - LDIDX_ELS = 0 # Indexed element-strided + # LDST element-strided + LDST_ELS = 0 # Indexed element-strided # LDST VLI for ffirst is in bit 0 LDST_VLI = 0 # BO bits diff --git a/src/openpower/decoder/power_insn.py b/src/openpower/decoder/power_insn.py index c6ea0ca5..54a4ead0 100644 --- a/src/openpower/decoder/power_insn.py +++ b/src/openpower/decoder/power_insn.py @@ -2214,23 +2214,21 @@ class LDSTImmBaseRM(PredicateWidthBaseRM): class LDSTImmSimpleRM(ElsBaseRM, ZZBaseRM, LDSTImmBaseRM): """ld/st immediate: simple mode""" + pi: BaseRM.mode[2] # Post-Increment Mode + lf: BaseRM.mode[4] # Fault-First Mode (not *Data-Dependent* Fail-First) zz: BaseRM.mode[3] - els: BaseRM.mode[4] + els: BaseRM.mode[0] dz: BaseRM.mode[3] sz: BaseRM.mode[3] - -class LDSTImmPostRM(LDSTImmBaseRM): - """ld/st immediate: postinc mode (and load-fault)""" - pi: BaseRM.mode[3] # Post-Increment Mode - lf: BaseRM.mode[4] # Fault-First Mode (not *Data-Dependent* Fail-First) - def specifiers(self, record): if self.pi: yield "pi" if self.lf: yield "lf" + yield from super().specifiers(record=record) + class LDSTFFRc1RM(FFRc1BaseRM, VLiBaseRM, LDSTImmBaseRM): """ld/st immediate&indexed: Rc=1: ffirst CR sel""" @@ -2242,32 +2240,20 @@ class LDSTFFRc1RM(FFRc1BaseRM, VLiBaseRM, LDSTImmBaseRM): yield from super().specifiers(record=record, mode="ff") -class LDSTFFRc0RM(FFRc0BaseRM, VLiBaseRM, ElsBaseRM, LDSTImmBaseRM): +class LDSTFFRc0RM(FFRc0BaseRM, VLiBaseRM, LDSTImmBaseRM): """ld/st immediate&indexed: Rc=0: ffirst z/nonz""" VLi: BaseRM.mode[0] inv: BaseRM.mode[2] - els: BaseRM.mode[3] RC1: BaseRM.mode[4] def specifiers(self, record): yield from super().specifiers(record=record, mode="ff") -class LDSTImmSatRM(ElsBaseRM, SatBaseRM, ZZBaseRM, LDSTImmBaseRM): - """ld/st immediate: sat mode: N=0/1 u/s""" - N: BaseRM.mode[2] - zz: BaseRM.mode[3] - els: BaseRM.mode[4] - dz: BaseRM.mode[3] - sz: BaseRM.mode[3] - - class LDSTImmRM(LDSTImmBaseRM): simple: LDSTImmSimpleRM - post: LDSTImmPostRM ffrc1: LDSTFFRc1RM ffrc0: LDSTFFRc0RM - sat: LDSTImmSatRM class LDSTIdxBaseRM(PredicateWidthBaseRM): @@ -2292,16 +2278,8 @@ class LDSTIdxSimpleRM(SEABaseRM, ZZCombinedBaseRM, LDSTIdxBaseRM): yield from super().specifiers(record=record) -class LDSTIdxSatRM(SatBaseRM, ZZCombinedBaseRM, LDSTIdxBaseRM): - """ld/st index: sat mode: N=0/1 u/s""" - N: BaseRM.mode[2] - dz: BaseRM.mode[3] - sz: BaseRM.mode[4] - - class LDSTIdxRM(LDSTIdxBaseRM): simple: LDSTIdxSimpleRM - sat: LDSTIdxSatRM ffrc1: LDSTFFRc1RM ffrc0: LDSTFFRc0RM @@ -3100,7 +3078,6 @@ class SpecifierPI(Specifier): def assemble(self, insn): selector = insn.select(record=self.record) - selector.mode[0] = 0b0 selector.mode[1] = 0b0 selector.mode[2] = 0b1 selector.pi = 0b1 @@ -3120,7 +3097,7 @@ class SpecifierLF(Specifier): def assemble(self, insn): selector = insn.select(record=self.record) - selector.mode[2] = 1 + selector.mode[1] = 0 selector.lf = 0b1 @@ -3295,11 +3272,9 @@ class RMSelector: # ironically/coincidentally this table is identical to NORMAL # mode except reserved in place of mr table = ( - (0b000000, 0b111000, "simple"), # simple (no Rc involved) - (0b001000, 0b111000, "post"), # post (no Rc involved) + (0b000000, 0b010000, "simple"), # simple (no Rc involved) (0b010001, 0b010001, "ffrc1"), # ffirst, Rc=1 (0b010000, 0b010001, "ffrc0"), # ffirst, Rc=0 - (0b100000, 0b110000, "sat"), # saturation (no Rc) ) search = ((int(self.insn.prefix.rm.ldst_imm.mode) << 1) | self.record.Rc) diff --git a/src/openpower/decoder/power_svp64_rm.py b/src/openpower/decoder/power_svp64_rm.py index fa02b652..f92a4edd 100644 --- a/src/openpower/decoder/power_svp64_rm.py +++ b/src/openpower/decoder/power_svp64_rm.py @@ -216,20 +216,12 @@ class SVP64RMModeDecode(Elaboratable): ##################### with m.Elif(is_ldst): with m.Switch(mode2): - with m.Case(0): # needs further decoding (LDST no mapreduce) - with m.If(is_ldstimm & mode[SVP64MODE.LDI_POST]): - comb += self.mode.eq(SVP64RMMode.NORMAL) - comb += self.ldst_postinc.eq(mode[SVP64MODE.LDI_PI]) - comb += self.ldst_ffirst.eq(mode[SVP64MODE.LDI_FF]) - with m.Elif(is_ldst): - comb += self.mode.eq(SVP64RMMode.NORMAL) + with m.Case(0, 2): # needs further decoding (LDST no mapreduce) + comb += self.mode.eq(SVP64RMMode.NORMAL) + comb += self.ldst_postinc.eq(mode[SVP64MODE.LDI_PI]) + comb += self.ldst_ffirst.eq(mode[SVP64MODE.LDI_FF]) with m.Case(1, 3): comb += self.mode.eq(SVP64RMMode.FFIRST) # ffirst - with m.Case(2): - with m.If(is_ldstimm): - comb += self.mode.eq(SVP64RMMode.SATURATE) # saturate - with m.Else(): - comb += self.mode.eq(SVP64RMMode.NORMAL) # els-bit # extract zeroing with m.If(is_ldst & ~is_ldstimm): # LDST-Indexed @@ -241,15 +233,10 @@ class SVP64RMModeDecode(Elaboratable): with m.Elif(is_ldstimm): # LDST-Immediate with m.Switch(mode2): - with m.Case(0): # simple mode - with m.If(~mode[2]): # (but not PI/LF) - # [MSB0-numbered] bits 0,1,2 of mode zero, use zz - comb += self.pred_sz.eq(mode[SVP64MODE.ZZ]) - comb += self.pred_dz.eq(mode[SVP64MODE.ZZ]) - with m.Case(2): # saturated mode - # saturated-mode also uses zz - comb += self.pred_sz.eq(mode[SVP64MODE.ZZ]) - comb += self.pred_dz.eq(mode[SVP64MODE.ZZ]) + with m.Case(0,2): # simple mode + # use zz + comb += self.pred_sz.eq(mode[SVP64MODE.ZZ]) + comb += self.pred_dz.eq(mode[SVP64MODE.ZZ]) # extract failfirst with m.If(self.mode == SVP64RMMode.FFIRST): # fail-first @@ -283,23 +270,12 @@ class SVP64RMModeDecode(Elaboratable): # extract els (element strided mode bit) # see https://libre-soc.org/openpower/sv/ldst/ els = Signal() - with m.If(is_ldstimm): # LD/ST-immediate - with m.Switch(mode2): - with m.Case(0): - with m.If(~mode[2]): # (but not PI/LF) - comb += els.eq(mode[SVP64MODE.ELS_NORMAL]) - with m.Case(2): - comb += els.eq(mode[SVP64MODE.ELS_SAT]) - with m.Case(1, 3): - with m.If(self.rc_in): - comb += els.eq(mode[SVP64MODE.ELS_FFIRST_PRED]) - with m.Else(): # LD/ST-Indexed - with m.Switch(mode2): - with m.Case(0, 2): - comb += els.eq(mode[SVP64MODE.LDIDX_ELS]) - with m.Case(1, 3): - with m.If(self.rc_in): - comb += els.eq(mode[SVP64MODE.ELS_FFIRST_PRED]) + 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): @@ -378,38 +354,6 @@ class SVP64RMModeDecode(Elaboratable): 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.If(is_ldst): - with m.If(is_ldstimm): - with m.Switch(mode2): - with m.Case(0): - comb += els.eq(mode[SVP64MODE.ELS_NORMAL]) - with m.Case(2): - comb += els.eq(mode[SVP64MODE.ELS_SAT]) - with m.Case(1, 3): - with m.If(self.rc_in): - comb += els.eq(mode[SVP64MODE.ELS_FFIRST_PRED]) - with m.Else(): - with m.Switch(mode2): - with m.Case(0, 2): - comb += els.eq(mode[SVP64MODE.LDIDX_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) - ###################### # Common fields (not many, sigh) ###################### -- 2.30.2