X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;ds=inline;f=src%2Fopenpower%2Fdecoder%2Fpower_insn.py;h=1f216388bb574a20ed5e1828ca9d1c0b61bc1b04;hb=c4a41c639a14722625e9be0cea85dfc203afdcc3;hp=5426bfb00e673eb9106145aa76385d1d2e675ab7;hpb=f54c84425556e71aa61fb0bc80d1a95590d2067a;p=openpower-isa.git diff --git a/src/openpower/decoder/power_insn.py b/src/openpower/decoder/power_insn.py index 5426bfb0..1f216388 100644 --- a/src/openpower/decoder/power_insn.py +++ b/src/openpower/decoder/power_insn.py @@ -1276,13 +1276,11 @@ class BaseRM(_Mapping): subvl: _Field = range(8, 10) mode: Mode.remap(range(19, 24)) smask: _Field = range(16, 19) - extra: Extra.remap(range(10, 19)) extra2: Extra2.remap(range(10, 19)) extra3: Extra3.remap(range(10, 19)) - @property - def specifiers(self): + def specifiers(self, record): subvl = int(self.subvl) if subvl > 0: yield { @@ -1301,25 +1299,59 @@ class BaseRM(_Mapping): class NormalLDSTBaseRM(BaseRM): - @property - def specifiers(self): - width = { + def specifiers(self, record): + widths = { 0b11: "8", 0b10: "16", 0b01: "32", } + predicates = { + # integer + (0, 0b001): "1<1""" - SVM: BaseRM.mode[3] +class NormalReservedRM(NormalBaseRM): + """normal: reserved""" + pass class NormalFailFirstRc1RM(NormalBaseRM): @@ -1360,12 +1392,20 @@ class NormalFailFirstRc1RM(NormalBaseRM): inv: BaseRM.mode[2] CR: BaseRM.mode[3, 4] + class NormalFailFirstRc0RM(NormalBaseRM): """normal: Rc=0: ffirst z/nonz""" inv: BaseRM.mode[2] VLi: BaseRM.mode[3] RC1: BaseRM.mode[4] + def specifiers(self, record): + if self.RC1: + inv = "~" if self.inv else "" + yield f"ff={inv}RC1" + + yield from super().specifiers(record=record) + class NormalSaturationRM(NormalBaseRM): """normal: sat mode: N=0/1 u/s, SUBVL=1""" @@ -1373,8 +1413,7 @@ class NormalSaturationRM(NormalBaseRM): dz: BaseRM.mode[3] sz: BaseRM.mode[4] - @property - def specifiers(self): + def specifiers(self, record): if self.dz: yield f"dz" if self.sz: @@ -1383,25 +1422,8 @@ class NormalSaturationRM(NormalBaseRM): yield "sats" else: yield "satu" - yield from super().specifiers - -class NormalSaturationExtRM(NormalBaseRM): - """normal: sat mode: N=0/1 u/s, SUBVL>1""" - N: BaseRM.mode[2] - zz: BaseRM.mode[3] - dz: BaseRM.mode[3] - sz: BaseRM.mode[3] - - @property - def specifiers(self): - if self.zz: - yield f"zz" - if self.N: - yield "sats" - else: - yield "satu" - yield from super().specifiers + yield from super().specifiers(record=record) class NormalPredResultRc1RM(NormalBaseRM): @@ -1418,22 +1440,23 @@ class NormalPredResultRc0RM(NormalBaseRM): dz: BaseRM.mode[3] sz: BaseRM.mode[3] - @property - def specifiers(self): + def specifiers(self, record): if self.zz: yield f"zz" - yield from super().specifiers + if self.RC1: + inv = "~" if self.inv else "" + yield f"pr={inv}RC1" + + yield from super().specifiers(record=record) class NormalRM(NormalBaseRM): simple: NormalSimpleRM smr: NormalScalarReduceRM - pmr: NormalParallelReduceRM - svmr: NormalSubvectorReduceRM + reserved: NormalReservedRM ffrc1: NormalFailFirstRc1RM ffrc0: NormalFailFirstRc0RM sat: NormalSaturationRM - satx: NormalSaturationExtRM prrc1: NormalPredResultRc1RM prrc0: NormalPredResultRc0RM @@ -1449,11 +1472,16 @@ class LDSTImmSimpleRM(LDSTImmBaseRM): dz: BaseRM.mode[3] sz: BaseRM.mode[3] - @property - def specifiers(self): + def specifiers(self, record): if self.zz: yield f"zz" - yield from super().specifiers + + yield from super().specifiers(record=record) + + +class LDSTImmReservedRM(LDSTImmBaseRM): + """ld/st immediate: reserved""" + pass class LDSTImmFailFirstRc1RM(LDSTImmBaseRM): @@ -1468,6 +1496,12 @@ class LDSTImmFailFirstRc0RM(LDSTImmBaseRM): els: BaseRM.mode[3] RC1: BaseRM.mode[4] + def specifiers(self, record): + if self.RC1: + inv = "~" if self.inv else "" + yield f"ff={inv}RC1" + + yield from super().specifiers(record=record) class LDSTImmSaturationRM(LDSTImmBaseRM): """ld/st immediate: sat mode: N=0/1 u/s""" @@ -1477,15 +1511,15 @@ class LDSTImmSaturationRM(LDSTImmBaseRM): dz: BaseRM.mode[3] sz: BaseRM.mode[3] - @property - def specifiers(self): + def specifiers(self, record): if self.zz: yield f"zz" if self.N: yield "sats" else: yield "satu" - yield from super().specifiers + + yield from super().specifiers(record=record) class LDSTImmPredResultRc1RM(LDSTImmBaseRM): @@ -1500,9 +1534,16 @@ class LDSTImmPredResultRc0RM(LDSTImmBaseRM): els: BaseRM.mode[3] RC1: BaseRM.mode[4] + def specifiers(self, record): + if self.RC1: + inv = "~" if self.inv else "" + yield f"pr={inv}RC1" + + yield from super().specifiers(record=record) class LDSTImmRM(LDSTImmBaseRM): simple: LDSTImmSimpleRM + reserved: LDSTImmReservedRM ffrc1: LDSTImmFailFirstRc1RM ffrc0: LDSTImmFailFirstRc0RM sat: LDSTImmSaturationRM @@ -1520,13 +1561,13 @@ class LDSTIdxSimpleRM(LDSTIdxBaseRM): sz: BaseRM.mode[3] dz: BaseRM.mode[3] - @property - def specifiers(self): + def specifiers(self, record): if self.dz: yield f"dz" if self.sz: yield f"sz" - yield from super().specifiers + + yield from super().specifiers(record=record) class LDSTIdxStrideRM(LDSTIdxBaseRM): @@ -1535,13 +1576,13 @@ class LDSTIdxStrideRM(LDSTIdxBaseRM): dz: BaseRM.mode[3] sz: BaseRM.mode[4] - @property - def specifiers(self): + def specifiers(self, record): if self.dz: yield f"dz" if self.sz: yield f"sz" - yield from super().specifiers + + yield from super().specifiers(record=record) class LDSTIdxSaturationRM(LDSTIdxBaseRM): @@ -1550,8 +1591,7 @@ class LDSTIdxSaturationRM(LDSTIdxBaseRM): dz: BaseRM.mode[3] sz: BaseRM.mode[4] - @property - def specifiers(self): + def specifiers(self, record): if self.dz: yield f"dz" if self.sz: @@ -1560,7 +1600,8 @@ class LDSTIdxSaturationRM(LDSTIdxBaseRM): yield "sats" else: yield "satu" - yield from super().specifiers + + yield from super().specifiers(record=record) class LDSTIdxPredResultRc1RM(LDSTIdxBaseRM): @@ -1577,11 +1618,14 @@ class LDSTIdxPredResultRc0RM(LDSTIdxBaseRM): dz: BaseRM.mode[3] sz: BaseRM.mode[3] - @property - def specifiers(self): + def specifiers(self, record): if self.zz: yield f"zz" - yield from super().specifiers + if self.RC1: + inv = "~" if self.inv else "" + yield f"pr={inv}RC1" + + yield from super().specifiers(record=record) class LDSTIdxRM(LDSTIdxBaseRM): @@ -1603,13 +1647,15 @@ class CROpSimpleRM(CROpBaseRM): RG: BaseRM[20] dz: BaseRM[22] - @property - def specifiers(self): + def specifiers(self, record): if self.dz: yield f"dz" if self.sz: yield f"sz" - yield from super().specifiers + if self.RG: + yield "mrr" + + yield from super().specifiers(record=record) class CROpScalarReduceRM(CROpBaseRM): @@ -1618,27 +1664,13 @@ class CROpScalarReduceRM(CROpBaseRM): SNZ: BaseRM[7] RG: BaseRM[20] - @property - def specifiers(self): + def specifiers(self, record): if self.sz: yield f"sz" - yield from super().specifiers + if self.RG: + yield "mrr" - -class CROpSubvectorReduceRM(CROpBaseRM): - """cr_op: subvector reduce mode, SUBVL>1""" - zz: BaseRM[6] - SNZ: BaseRM[7] - RG: BaseRM[20] - SVM: BaseRM[22] - dz: BaseRM[6] - sz: BaseRM[6] - - @property - def specifiers(self): - if self.zz: - yield f"zz" - yield from super().specifiers + yield from super().specifiers(record=record) class CROpReservedRM(CROpBaseRM): @@ -1649,11 +1681,13 @@ class CROpReservedRM(CROpBaseRM): dz: BaseRM[6] sz: BaseRM[6] - @property - def specifiers(self): + def specifiers(self, record): if self.zz: yield f"zz" - yield from super().specifiers + if self.RG: + yield "mrr" + + yield from super().specifiers(record=record) class CROpFailFirst3RM(CROpBaseRM): @@ -1666,11 +1700,10 @@ class CROpFailFirst3RM(CROpBaseRM): dz: BaseRM[6] sz: BaseRM[6] - @property - def specifiers(self): + def specifiers(self, record): if self.zz: yield f"zz" - yield from super().specifiers + yield from super().specifiers(record=record) class CROpFailFirst5RM(CROpBaseRM): @@ -1681,19 +1714,17 @@ class CROpFailFirst5RM(CROpBaseRM): inv: BaseRM[21] dz: BaseRM[22] - @property - def specifiers(self): + def specifiers(self, record): if self.dz: yield f"dz" if self.sz: yield f"sz" - yield from super().specifiers + yield from super().specifiers(record=record) class CROpRM(CROpBaseRM): simple: CROpSimpleRM smr: CROpScalarReduceRM - svmr: CROpSubvectorReduceRM reserved: CROpReservedRM ff3: CROpFailFirst3RM ff5: CROpFailFirst5RM @@ -1745,114 +1776,102 @@ class RM(BaseRM): def select(self, record, Rc): rm = self + # the idea behind these tables is that they are now literally + # in identical format to insndb.csv and minor_xx.csv and can + # be done precisely as that. the only thing to watch out for + # is the insertion of Rc=1 as a "mask/value" bit and likewise + # regtype detection (3-bit BF/BFA, 5-bit BA/BB/BT) also inserted + # as the LSB. + table = None if record.svp64.mode is _SVMode.NORMAL: + # concatenate mode 5-bit with Rc (LSB) then do a mask/map search + # mode Rc mask Rc member + table = ( + (0b000000, 0b111000, "simple"), # simple (no Rc) + (0b001000, 0b111000, "smr"), # mapreduce (no Rc) + (0b010000, 0b110001, "ffrc0"), # ffirst, Rc=0 + (0b010001, 0b110001, "ffrc1"), # ffirst, Rc=1 + (0b100000, 0b110000, "sat"), # saturation (no Rc) + (0b110000, 0b110001, "prrc0"), # predicate, Rc=0 + (0b110001, 0b110001, "prrc1"), # predicate, Rc=1 + ) rm = rm.normal - if rm.mode[0:2] == 0b00: - if rm.mode[2] == 0b0: - rm = rm.simple - else: - if self.subvl == 0b00: - if rm.mode[3] == 0b0: - rm = rm.smr - else: - rm = rm.pmr - else: - if rm.mode[4] == 0b0: - rm = rm.svmr - #else: - # rm = rm.pu - elif rm.mode[0:2] == 0b01: - if Rc: - rm = rm.ffrc1 - else: - rm = rm.ffrc0 - elif rm.mode[0:2] == 0b10: - if self.subvl == 0b00: - rm = rm.sat - else: - if rm.mode[4]: - rm = rm.satx - #else: - # rm = rm.satpu - elif rm.mode[0:2] == 0b11: - if Rc: - rm = rm.prrc1 - else: - rm = rm.prrc0 + search = ((int(rm.mode) << 1) | Rc) elif record.svp64.mode is _SVMode.LDST_IMM: + # concatenate mode 5-bit with Rc (LSB) then do a mask/map search + # mode Rc mask Rc member + # ironically/coincidentally this table is identical to NORMAL + # mode except reserved in place of smr + table = ( + (0b000000, 0b111000, "simple"), # simple (no Rc) + (0b001000, 0b111000, "reserved"), # rsvd (no Rc) + (0b010000, 0b110001, "ffrc0"), # ffirst, Rc=0 + (0b010001, 0b110001, "ffrc1"), # ffirst, Rc=1 + (0b100000, 0b110000, "sat"), # saturation (no Rc) + (0b110000, 0b110001, "prrc0"), # predicate, Rc=0 + (0b110001, 0b110001, "prrc1"), # predicate, Rc=1 + ) rm = rm.ldst_imm - if rm.mode[0:2] == 0b00: - if rm.mode[2] == 0b0: - rm = rm.simple - #else: - # rm = rm.spu - elif rm.mode[0:2] == 0b01: - if Rc: - rm = rm.ffrc1 - else: - rm = rm.ffrc0 - elif rm.mode[0:2] == 0b10: - rm = rm.sat - elif rm.mode[0:2] == 0b11: - if Rc: - rm = rm.prrc1 - else: - rm = rm.prrc0 - - elif record.svp64.mode is _SVMode.LDST_IMM: + search = ((int(rm.mode) << 1) | Rc) + + elif record.svp64.mode is _SVMode.LDST_IDX: + # concatenate mode 5-bit with Rc (LSB) then do a mask/map search + # mode Rc mask Rc member + table = ( + (0b000000, 0b111000, "simple"), # simple (no Rc) + (0b010000, 0b110000, "stride"), # strided, (no Rc) + (0b100000, 0b110000, "sat"), # saturation (no Rc) + (0b110000, 0b110001, "prrc0"), # predicate, Rc=0 + (0b110001, 0b110001, "prrc1"), # predicate, Rc=1 + ) rm = rm.ldst_idx - if rm.mode[0:2] == 0b00: - rm = rm.simple - elif rm.mode[0:2] == 0b01: - rm = rm.stride - elif rm.mode[0:2] == 0b10: - rm = rm.sat - elif rm.mode[0:2] == 0b11: - if Rc: - rm = rm.prrc1 - else: - rm = rm.prrc0 + search = ((int(rm.mode) << 1) | Rc) elif record.svp64.mode is _SVMode.CROP: - rm = rm.cr_op - if rm[19] == 0b0: - if rm[21] == 0b0: - rm = rm.simple - else: - if self.subvl == 0: - rm = rm.smr - else: - if rm[23] == 0b0: - rm = rm.svmr - else: - rm = rm.reserved + # concatenate mode 5-bit with regtype (LSB) then do mask/map search + # mode 3b mask 3b member + table = ( + (0b000000, 0b111000, "simple"), # simple + (0b001000, 0b111000, "smr"), # mapreduce + (0b100000, 0b100000, "ff5"), # failfirst, 5-bit CR + (0b100001, 0b100001, "ff3"), # failfirst, 3-bit CR + ) + # determine CR type, 5-bit (BA/BB/BT) or 3-bit Field (BF/BFA) + regtype = None + for idx in range(0, 4): + for entry in record.svp64.extra[idx]: + if entry.regtype is _SVExtraRegType.DST: + if regtype is not None: + raise ValueError(record.svp64) + regtype = _RegType(entry.reg) + if regtype is _RegType.CR_REG: + regtype = 0 # 5-bit + elif regtype is _RegType.CR_BIT: + regtype = 1 # 3-bit else: - regtype = None - for idx in range(0, 4): - for entry in record.svp64.extra[idx]: - if entry.regtype is _SVExtraRegType.DST: - if regtype is not None: - raise ValueError(record.svp64) - regtype = _RegType(entry.reg) - if regtype is _RegType.CR_REG: - rm = rm.ff5 - elif regtype is _RegType.CR_BIT: - rm = rm.ff3 - else: - raise ValueError(record.svp64) + raise ValueError(record.svp64) + # finally provide info for search + rm = rm.cr_op + search = ((int(rm.mode) << 1) | (regtype or 0)) elif record.svp64.mode is _SVMode.BRANCH: - if rm[19] == 0b0: - if rm[20] == 0b0: - rm = rm.simple - else: - rm = rm.vls - else: - if rm[20] == 0b0: - rm = rm.ctr - else: - rm = rm.ctrvls + # just mode 5-bit. could be reduced down to 2, oh well. + # mode mask action(getattr) + table = [(0b00000, 0b11000, "simple"), # simple + (0b01000, 0b11000, "vls"), # VLset + (0b10000, 0b11000, "ctr"), # CTR mode + (0b11000, 0b11000, "ctrvls"), # CTR+VLset mode + ] + # slightly weird: doesn't have a 5-bit "mode" field like others + search = int(rm[19:23]) + + # look up in table + if table is not None: + for (value, mask, member) in table: + if ((value & search) == (mask & search)): + rm = getattr(rm, member) + break if rm.__class__ is self.__class__: raise ValueError(self) @@ -1905,12 +1924,13 @@ class SVP64Instruction(PrefixedInstruction): Rc = False if record.mdwn.operands["Rc"] is not None: - Rc = bool(self.suffix[record.fields["Rc"]]) + Rc = bool(record.mdwn.operands["Rc"].value) rm = self.prefix.rm.select(record=record, Rc=Rc) - specifiers = tuple(rm.specifiers) + specifiers = tuple(rm.specifiers(record=record)) if specifiers: - specifiers = f"/{'/'.join(specifiers)}" + specifiers = "/".join(specifiers) + specifiers = f"/{specifiers}" else: specifiers = ""