(start, end) = value
if start < 0 or end < 0 or start >= end:
raise ValueError(value)
-
+
self.__start = start
self.__end = end
spec = _SelectableInt(value=spec.value, bits=bits)
if vector:
value = ((value << vector_shift) | (spec << spec_shift))
- span = (span + spec_span + ((spec_shift * ('{0}',))))
+ span = (span + spec_span + ((spec_shift * ("{0}",))))
else:
value = ((spec << scalar_shift) | value)
- span = ((spec_shift * ('{0}',)) + spec_span + span)
+ span = ((spec_shift * ("{0}",)) + spec_span + span)
(value, span) = self.sv_spec_leave(value=value, span=span,
origin_value=origin_value, origin_span=origin_span)
value = insn[span]
if verbosity >= Verbosity.VERBOSE:
- span = tuple(map(str, span))
+ span = (tuple(map(str, span)) + ("{0}", "{0}"))
yield f"{indent}{self.name} = EXTS({field} || 0b00))"
yield f"{indent}{indent}{field}"
yield f"{indent}{indent}{indent}{int(value):0{value.bits}b}00"
- yield f"{indent}{indent}{indent}{', '.join(span + ('{0}', '{0}'))}"
+ yield f"{indent}{indent}{indent}{', '.join(span)}"
else:
yield hex(_selectconcat(value,
_SelectableInt(value=0b00, bits=2)).to_signed_int())
operands = ""
if dynamic_operands:
- operands += f" {','.join(dynamic_operands)}"
+ operands += " "
+ operands += ",".join(dynamic_operands)
if static_operands:
- operands += f" ({' '.join(static_operands)})"
+ operands += " "
+ operands += " ".join(static_operands)
return f"{prefix}{record.name}{operands}"
operands = tuple(map(_operator.itemgetter(1),
self.dynamic_operands(db=db, verbosity=verbosity)))
if operands:
- yield f"{blob}{record.name} {','.join(operands)}"
+ operands = ",".join(operands)
+ yield f"{blob}{record.name} {operands}"
else:
yield f"{blob}{record.name}"
def disassemble(self, verbosity=Verbosity.NORMAL):
if verbosity >= Verbosity.VERBOSE:
indent = (" " * 4)
- for (name, value, members) in self.traverse(path="RM"):
+ for (name, span) in self.traverse(path="RM"):
+ value = self.storage[span]
yield f"{name}"
yield f"{indent}{int(value):0{value.bits}b}"
- yield f"{indent}{', '.join(map(str, members))}"
+ yield f"{indent}{', '.join(map(str, span))}"
+
+
+class FFPRRc1BaseRM(BaseRM):
+ def specifiers(self, record, mode):
+ inv = _SelectableInt(value=int(self.inv), bits=1)
+ CR = _SelectableInt(value=int(self.CR), bits=2)
+ mask = int(_selectconcat(CR, inv))
+ predicate = PredicateBaseRM.predicate(True, mask)
+ yield f"{mode}={predicate}"
+
+ yield from super().specifiers(record=record)
+
+
+class FFPRRc0BaseRM(BaseRM):
+ def specifiers(self, record, mode):
+ if self.RC1:
+ inv = "~" if self.inv else ""
+ yield f"{mode}={inv}RC1"
+
+ yield from super().specifiers(record=record)
+
+
+class SatBaseRM(BaseRM):
+ def specifiers(self, record):
+ if self.N:
+ yield "sats"
+ else:
+ yield "satu"
+
+ yield from super().specifiers(record=record)
+
+
+class ZZBaseRM(BaseRM):
+ def specifiers(self, record):
+ if self.zz:
+ yield "zz"
+
+ yield from super().specifiers(record=record)
+
+
+class DZBaseRM(BaseRM):
+ def specifiers(self, record):
+ if self.dz:
+ yield "dz"
+
+ yield from super().specifiers(record=record)
-class NormalLDSTBaseRM(BaseRM):
+class SZBaseRM(BaseRM):
def specifiers(self, record):
- widths = {
+ if self.sz:
+ yield "sz"
+
+ yield from super().specifiers(record=record)
+
+
+class MRBaseRM(BaseRM):
+ def specifiers(self, record):
+ if self.RG:
+ yield "mrr"
+ else:
+ yield "mr"
+
+ yield from super().specifiers(record=record)
+
+
+class ElsBaseRM(BaseRM):
+ def specifiers(self, record):
+ if self.els:
+ yield "els"
+
+ yield from super().specifiers(record=record)
+
+
+class WidthBaseRM(BaseRM):
+ @staticmethod
+ def width(FP, width):
+ width = {
0b11: "8",
0b10: "16",
0b01: "32",
- }
- predicates = {
+ }.get(width)
+ if width is None:
+ return None
+ if FP:
+ width = ("fp" + width)
+ return width
+
+ def specifiers(self, record):
+ # elwidths: use "w=" if same otherwise dw/sw
+ # FIXME this should consider FP instructions
+ FP = False
+ dw = WidthBaseRM.width(FP, int(self.elwidth))
+ sw = WidthBaseRM.width(FP, int(self.ewsrc))
+ if dw == sw and dw:
+ yield ("w=" + dw)
+ else:
+ if dw:
+ yield ("dw=" + dw)
+ if sw:
+ yield ("sw=" + sw)
+
+ yield from super().specifiers(record=record)
+
+
+class PredicateBaseRM(BaseRM):
+ @staticmethod
+ def predicate(CR, mask):
+ return {
# integer
- (0, 0b001): "1<<r3",
- (0, 0b010): "r3",
- (0, 0b011): "~r3",
- (0, 0b100): "r10",
- (0, 0b101): "~r10",
- (0, 0b110): "r30",
- (0, 0b111): "~r30",
+ (False, 0b001): "1<<r3",
+ (False, 0b010): "r3",
+ (False, 0b011): "~r3",
+ (False, 0b100): "r10",
+ (False, 0b101): "~r10",
+ (False, 0b110): "r30",
+ (False, 0b111): "~r30",
# CRs
- (1, 0b000): "lt",
- (1, 0b001): "ge",
- (1, 0b010): "gt",
- (1, 0b011): "le",
- (1, 0b100): "eq",
- (1, 0b101): "ne",
- (1, 0b110): "so",
- (1, 0b111): "ns",
- }
+ (True, 0b000): "lt",
+ (True, 0b001): "ge",
+ (True, 0b010): "gt",
+ (True, 0b011): "le",
+ (True, 0b100): "eq",
+ (True, 0b101): "ne",
+ (True, 0b110): "so",
+ (True, 0b111): "ns",
+ }.get((CR, mask))
- mmode = int(self.mmode)
+ def specifiers(self, record):
+ # predication - single and twin
+ # use "m=" if same otherwise sm/dm
+ CR = (int(self.mmode) == 1)
mask = int(self.mask)
+ sm = dm = PredicateBaseRM.predicate(CR, mask)
if record.svp64.ptype is _SVPtype.P2:
- (smask, dmask) = (int(self.smask), mask)
- else:
- (smask, dmask) = (mask, mask)
- if all((smask, dmask)) and (smask == dmask):
- yield f"m={predicates[(mmode, smask)]}"
- else:
- sw = predicates.get((mmode, smask))
- dw = predicates.get((mmode, dmask))
- if sw:
- yield f"sm={sw}"
- if dw:
- yield f"dm={dw}"
-
- dw = int(self.elwidth)
- sw = int(self.ewsrc)
- if all((dw, sw)) and (dw == sw):
- yield f"w={widths[dw]}"
+ smask = int(self.smask)
+ sm = PredicateBaseRM.predicate(CR, smask)
+ if sm == dm and dm:
+ yield ("m=" + dm)
else:
- if dw != 0b00:
- yield f"dw={widths[dw]}"
- if sw != 0b00:
- yield f"sw={widths[sw]}"
+ if sm:
+ yield ("sm=" + sm)
+ if dm:
+ yield ("dm=" + dm)
yield from super().specifiers(record=record)
-class NormalBaseRM(NormalLDSTBaseRM):
+class PredicateWidthBaseRM(WidthBaseRM, PredicateBaseRM):
pass
-class NormalSimpleRM(NormalBaseRM):
+class NormalBaseRM(PredicateWidthBaseRM):
+ """
+ Normal mode
+ https://libre-soc.org/openpower/sv/normal/
+ """
+ pass
+
+
+class NormalSimpleRM(DZBaseRM, SZBaseRM, NormalBaseRM):
"""normal: simple mode"""
dz: BaseRM.mode[3]
sz: BaseRM.mode[4]
def specifiers(self, record):
- if self.dz:
- yield f"dz"
- if self.sz:
- yield f"sz"
yield from super().specifiers(record=record)
-class NormalScalarReduceRM(NormalBaseRM):
+class NormalSMRRM(MRBaseRM, NormalBaseRM):
"""normal: scalar reduce mode (mapreduce), SUBVL=1"""
RG: BaseRM.mode[4]
- def specifiers(self, record):
- if self.RG:
- yield "mrr"
-
- yield from super().specifiers(record=record)
-
class NormalReservedRM(NormalBaseRM):
"""normal: reserved"""
pass
-class NormalFailFirstRc1RM(NormalBaseRM):
+class NormalFFRc1RM(FFPRRc1BaseRM, NormalBaseRM):
"""normal: Rc=1: ffirst CR sel"""
inv: BaseRM.mode[2]
CR: BaseRM.mode[3, 4]
+ def specifiers(self, record):
+ yield from super().specifiers(record=record, mode="ff")
+
-class NormalFailFirstRc0RM(NormalBaseRM):
+class NormalFFRc0RM(FFPRRc0BaseRM, 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.VLi:
+ yield "vli"
+
+ yield from super().specifiers(record=record, mode="ff")
+
-class NormalSaturationRM(NormalBaseRM):
+class NormalSatRM(SatBaseRM, DZBaseRM, SZBaseRM, NormalBaseRM):
"""normal: sat mode: N=0/1 u/s, SUBVL=1"""
N: BaseRM.mode[2]
dz: BaseRM.mode[3]
sz: BaseRM.mode[4]
- def specifiers(self, record):
- if self.dz:
- yield f"dz"
- if self.sz:
- yield f"sz"
- if self.N:
- yield "sats"
- else:
- yield "satu"
-
- yield from super().specifiers(record=record)
-
-class NormalPredResultRc1RM(NormalBaseRM):
+class NormalPRRc1RM(FFPRRc1BaseRM, NormalBaseRM):
"""normal: Rc=1: pred-result CR sel"""
inv: BaseRM.mode[2]
CR: BaseRM.mode[3, 4]
+ def specifiers(self, record):
+ yield from super().specifiers(record=record, mode="pr")
+
-class NormalPredResultRc0RM(NormalBaseRM):
+class NormalPRRc0RM(FFPRRc0BaseRM, ZZBaseRM, NormalBaseRM):
"""normal: Rc=0: pred-result z/nonz"""
inv: BaseRM.mode[2]
zz: BaseRM.mode[3]
sz: BaseRM.mode[3]
def specifiers(self, record):
- if self.zz:
- yield f"zz"
-
- yield from super().specifiers(record=record)
+ yield from super().specifiers(record=record, mode="pr")
class NormalRM(NormalBaseRM):
simple: NormalSimpleRM
- smr: NormalScalarReduceRM
+ smr: NormalSMRRM
reserved: NormalReservedRM
- ffrc1: NormalFailFirstRc1RM
- ffrc0: NormalFailFirstRc0RM
- sat: NormalSaturationRM
- prrc1: NormalPredResultRc1RM
- prrc0: NormalPredResultRc0RM
-
-
-class LDSTImmBaseRM(NormalLDSTBaseRM):
+ ffrc1: NormalFFRc1RM
+ ffrc0: NormalFFRc0RM
+ sat: NormalSatRM
+ prrc1: NormalPRRc1RM
+ prrc0: NormalPRRc0RM
+
+
+class LDSTImmBaseRM(PredicateWidthBaseRM):
+ """
+ LD/ST Immediate mode
+ https://libre-soc.org/openpower/sv/ldst/
+ """
pass
-class LDSTImmSimpleRM(LDSTImmBaseRM):
+class LDSTImmSimpleRM(ElsBaseRM, ZZBaseRM, LDSTImmBaseRM):
"""ld/st immediate: simple mode"""
zz: BaseRM.mode[3]
els: BaseRM.mode[4]
dz: BaseRM.mode[3]
sz: BaseRM.mode[3]
- def specifiers(self, record):
- if self.zz:
- yield f"zz"
-
- yield from super().specifiers(record=record)
-
class LDSTImmReservedRM(LDSTImmBaseRM):
"""ld/st immediate: reserved"""
pass
-class LDSTImmFailFirstRc1RM(LDSTImmBaseRM):
+class LDSTImmFFRc1RM(FFPRRc1BaseRM, LDSTImmBaseRM):
"""ld/st immediate: Rc=1: ffirst CR sel"""
inv: BaseRM.mode[2]
CR: BaseRM.mode[3, 4]
+ def specifiers(self, record):
+ yield from super().specifiers(record=record, mode="ff")
+
-class LDSTImmFailFirstRc0RM(LDSTImmBaseRM):
+class LDSTImmFFRc0RM(FFPRRc0BaseRM, ElsBaseRM, LDSTImmBaseRM):
"""ld/st immediate: Rc=0: ffirst z/nonz"""
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 LDSTImmSaturationRM(LDSTImmBaseRM):
+class LDSTImmSatRM(ElsBaseRM, SatBaseRM, ZZBaseRM, LDSTImmBaseRM):
"""ld/st immediate: sat mode: N=0/1 u/s"""
N: BaseRM.mode[2]
zz: BaseRM.mode[3]
dz: BaseRM.mode[3]
sz: BaseRM.mode[3]
- def specifiers(self, record):
- if self.zz:
- yield f"zz"
- if self.N:
- yield "sats"
- else:
- yield "satu"
-
- yield from super().specifiers(record=record)
-
-class LDSTImmPredResultRc1RM(LDSTImmBaseRM):
+class LDSTImmPRRc1RM(FFPRRc1BaseRM, LDSTImmBaseRM):
"""ld/st immediate: Rc=1: pred-result CR sel"""
inv: BaseRM.mode[2]
CR: BaseRM.mode[3, 4]
+ def specifiers(self, record):
+ yield from super().specifiers(record=record, mode="pr")
+
-class LDSTImmPredResultRc0RM(LDSTImmBaseRM):
+class LDSTImmPRRc0RM(FFPRRc0BaseRM, ElsBaseRM, LDSTImmBaseRM):
"""ld/st immediate: Rc=0: pred-result z/nonz"""
inv: BaseRM.mode[2]
els: BaseRM.mode[3]
RC1: BaseRM.mode[4]
+ def specifiers(self, record):
+ yield from super().specifiers(record=record, mode="pr")
+
class LDSTImmRM(LDSTImmBaseRM):
simple: LDSTImmSimpleRM
reserved: LDSTImmReservedRM
- ffrc1: LDSTImmFailFirstRc1RM
- ffrc0: LDSTImmFailFirstRc0RM
- sat: LDSTImmSaturationRM
- prrc1: LDSTImmPredResultRc1RM
- prrc0: LDSTImmPredResultRc0RM
-
-
-class LDSTIdxBaseRM(NormalLDSTBaseRM):
+ ffrc1: LDSTImmFFRc1RM
+ ffrc0: LDSTImmFFRc0RM
+ sat: LDSTImmSatRM
+ prrc1: LDSTImmPRRc1RM
+ prrc0: LDSTImmPRRc0RM
+
+
+class LDSTIdxBaseRM(PredicateWidthBaseRM):
+ """
+ LD/ST Indexed mode
+ https://libre-soc.org/openpower/sv/ldst/
+ """
pass
-class LDSTIdxSimpleRM(LDSTIdxBaseRM):
+class LDSTIdxSimpleRM(DZBaseRM, SZBaseRM, LDSTIdxBaseRM):
"""ld/st index: simple mode"""
SEA: BaseRM.mode[2]
- sz: BaseRM.mode[3]
dz: BaseRM.mode[3]
-
- def specifiers(self, record):
- if self.dz:
- yield f"dz"
- if self.sz:
- yield f"sz"
-
- yield from super().specifiers(record=record)
+ sz: BaseRM.mode[4]
-class LDSTIdxStrideRM(LDSTIdxBaseRM):
+class LDSTIdxStrideRM(DZBaseRM, SZBaseRM, LDSTIdxBaseRM):
"""ld/st index: strided (scalar only source)"""
SEA: BaseRM.mode[2]
dz: BaseRM.mode[3]
sz: BaseRM.mode[4]
- def specifiers(self, record):
- if self.dz:
- yield f"dz"
- if self.sz:
- yield f"sz"
-
- yield from super().specifiers(record=record)
-
-class LDSTIdxSaturationRM(LDSTIdxBaseRM):
+class LDSTIdxSatRM(SatBaseRM, DZBaseRM, SZBaseRM, LDSTIdxBaseRM):
"""ld/st index: sat mode: N=0/1 u/s"""
N: BaseRM.mode[2]
dz: BaseRM.mode[3]
sz: BaseRM.mode[4]
- def specifiers(self, record):
- if self.dz:
- yield f"dz"
- if self.sz:
- yield f"sz"
- if self.N:
- yield "sats"
- else:
- yield "satu"
-
- yield from super().specifiers(record=record)
-
-class LDSTIdxPredResultRc1RM(LDSTIdxBaseRM):
+class LDSTIdxPRRc1RM(LDSTIdxBaseRM):
"""ld/st index: Rc=1: pred-result CR sel"""
inv: BaseRM.mode[2]
CR: BaseRM.mode[3, 4]
+ def specifiers(self, record):
+ yield from super().specifiers(record=record, mode="pr")
+
-class LDSTIdxPredResultRc0RM(LDSTIdxBaseRM):
+class LDSTIdxPRRc0RM(FFPRRc0BaseRM, ZZBaseRM, LDSTIdxBaseRM):
"""ld/st index: Rc=0: pred-result z/nonz"""
inv: BaseRM.mode[2]
zz: BaseRM.mode[3]
sz: BaseRM.mode[3]
def specifiers(self, record):
- if self.zz:
- yield f"zz"
-
- yield from super().specifiers(record=record)
+ yield from super().specifiers(record=record, mode="pr")
class LDSTIdxRM(LDSTIdxBaseRM):
simple: LDSTIdxSimpleRM
stride: LDSTIdxStrideRM
- sat: LDSTIdxSaturationRM
- prrc1: LDSTIdxPredResultRc1RM
- prrc0: LDSTIdxPredResultRc0RM
+ sat: LDSTIdxSatRM
+ prrc1: LDSTIdxPRRc1RM
+ prrc0: LDSTIdxPRRc0RM
+
class CROpBaseRM(BaseRM):
- pass
+ """
+ CR ops mode
+ https://libre-soc.org/openpower/sv/cr_ops/
+ """
+ SNZ: BaseRM[7]
-class CROpSimpleRM(CROpBaseRM):
+class CROpSimpleRM(DZBaseRM, SZBaseRM, CROpBaseRM):
"""cr_op: simple mode"""
- sz: BaseRM[6]
- SNZ: BaseRM[7]
RG: BaseRM[20]
dz: BaseRM[22]
+ sz: BaseRM[23]
def specifiers(self, record):
- if self.dz:
- yield f"dz"
- if self.sz:
- yield f"sz"
if self.RG:
- yield "mrr"
+ yield "rg" # simple CR Mode reports /rg
yield from super().specifiers(record=record)
-
-class CROpScalarReduceRM(CROpBaseRM):
+class CROpSMRRM(MRBaseRM, DZBaseRM, SZBaseRM, CROpBaseRM):
"""cr_op: scalar reduce mode (mapreduce), SUBVL=1"""
- sz: BaseRM[6]
- SNZ: BaseRM[7]
RG: BaseRM[20]
-
- def specifiers(self, record):
- if self.sz:
- yield f"sz"
- if self.RG:
- yield "mrr"
-
- yield from super().specifiers(record=record)
-
-
-class CROpReservedRM(CROpBaseRM):
- """cr_op: reserved"""
- zz: BaseRM[6]
- SNZ: BaseRM[7]
- RG: BaseRM[20]
- dz: BaseRM[6]
- sz: BaseRM[6]
-
- def specifiers(self, record):
- if self.zz:
- yield f"zz"
- if self.RG:
- yield "mrr"
-
- yield from super().specifiers(record=record)
+ dz: BaseRM[22]
+ sz: BaseRM[23]
-class CROpFailFirst3RM(CROpBaseRM):
+class CROpFF3RM(ZZBaseRM, CROpBaseRM):
"""cr_op: ffirst 3-bit mode"""
- zz: BaseRM[6]
- SNZ: BaseRM[7]
VLI: BaseRM[20]
inv: BaseRM[21]
CR: BaseRM[22, 23]
- dz: BaseRM[6]
+ zz: BaseRM[6]
sz: BaseRM[6]
+ dz: BaseRM[6]
def specifiers(self, record):
- if self.zz:
- yield f"zz"
- yield from super().specifiers(record=record)
+ yield from super().specifiers(record=record, mode="ff")
-class CROpFailFirst5RM(CROpBaseRM):
+class CROpFF5RM(DZBaseRM, SZBaseRM, CROpBaseRM):
"""cr_op: ffirst 5-bit mode"""
- sz: BaseRM[6]
- SNZ: BaseRM[7]
VLI: BaseRM[20]
inv: BaseRM[21]
dz: BaseRM[22]
+ sz: BaseRM[23]
def specifiers(self, record):
- if self.dz:
- yield f"dz"
- if self.sz:
- yield f"sz"
yield from super().specifiers(record=record)
class CROpRM(CROpBaseRM):
simple: CROpSimpleRM
- smr: CROpScalarReduceRM
- reserved: CROpReservedRM
- ff3: CROpFailFirst3RM
- ff5: CROpFailFirst5RM
+ smr: CROpSMRRM
+ ff3: CROpFF3RM
+ ff5: CROpFF5RM
+# ********************
+# Branches mode
+# https://libre-soc.org/openpower/sv/branches/
class BranchBaseRM(BaseRM):
ALL: BaseRM[4]
SNZ: BaseRM[5]
SLu: BaseRM[18]
LRu: BaseRM[22]
sz: BaseRM[23]
+ CTR: BaseRM[19]
+ VLS: BaseRM[20]
+
+ def specifiers(self, record):
+ if self.ALL:
+ yield "all"
+
+ # /sz
+ # branch.sz=1
+ # branch.snz=0
+ # /snz
+ # branch.sz=1
+ # branch.snz=1
+ if self.SNZ:
+ if not self.sz:
+ raise ValueError(self.sz)
+ yield "snz"
+ elif self.sz:
+ yield "sz"
+
+ if self.SL:
+ yield "sl"
+ if self.SLu:
+ yield "slu"
+ if self.LRu:
+ yield "lru"
+
+ # Branch modes lack source mask.
+ # Therefore a custom code is needed.
+ CR = (int(self.mmode) == 1)
+ mask = int(self.mask)
+ m = PredicateBaseRM.predicate(CR, mask)
+ if m is not None:
+ yield ("m=" + m)
+
+ yield from super().specifiers(record=record)
class BranchSimpleRM(BranchBaseRM):
VSb: BaseRM[7]
VLI: BaseRM[21]
+ def specifiers(self, record):
+ yield {
+ (0b0, 0b0): "vs",
+ (0b0, 0b1): "vsi",
+ (0b1, 0b0): "vsb",
+ (0b1, 0b1): "vsbi",
+ }[int(self.VSb), int(self.VLI)]
+
+ yield from super().specifiers(record=record)
+
class BranchCTRRM(BranchBaseRM):
"""branch: CTR-test mode"""
CTi: BaseRM[6]
+ def specifiers(self, record):
+ if self.CTi:
+ yield "cti"
+ else:
+ yield "ctr"
+
+ yield from super().specifiers(record=record)
+
class BranchCTRVLSRM(BranchVLSRM, BranchCTRRM):
"""branch: CTR-test+VLSET mode"""
ldst_imm: LDSTImmRM
ldst_idx: LDSTIdxRM
cr_op: CROpRM
+ branch: BranchRM
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 action(getattr)
- 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
- ]
-
+ # 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
- search = (int(rm.mode) << 1) | Rc
- for (val, mask, action) in table:
- if (val&search) == (mask&search):
- rm = getattr(rm, action)
- break
+ 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 action(getattr)
+ # 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
- ]
+ 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
- search = (int(rm.mode) << 1) | Rc
- for (val, mask, action) in table:
- if (val&search) == (mask&search):
- rm = getattr(rm, action)
- break
+ 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 action(getattr)
- 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
- ]
+ # 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
- search = (int(rm.mode) << 1) | Rc
- for (val, mask, action) in table:
- if (val&search) == (mask&search):
- rm = getattr(rm, action)
- break
+ 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:
- rm = rm.smr
+ # 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 2-bit
+ # mode mask member
+ table = (
+ (0b00, 0b11, "simple"), # simple
+ (0b01, 0b11, "vls"), # VLset
+ (0b10, 0b11, "ctr"), # CTR mode
+ (0b11, 0b11, "ctrvls"), # CTR+VLset mode
+ )
+ # slightly weird: doesn't have a 5-bit "mode" field like others
+ rm = rm.branch
+ search = int(rm.mode[0, 1])
+
+ # 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)
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(record=record))
- if specifiers:
- specifiers = "/".join(specifiers)
- specifiers = f"/{specifiers}"
- else:
- specifiers = ""
+ # convert specifiers to /x/y/z (sorted lexicographically)
+ specifiers = sorted(rm.specifiers(record=record))
+ if specifiers: # if any add one extra to get the extra "/"
+ specifiers = ([""] + specifiers)
+ specifiers = "/".join(specifiers)
+ # convert operands to " ,x,y,z"
operands = tuple(map(_operator.itemgetter(1),
self.dynamic_operands(db=db, verbosity=verbosity)))
- if operands:
- operands = f" {','.join(operands)}"
- else:
- operands = ""
+ operands = ",".join(operands)
+ if len(operands) > 0: # if any separate with a space
+ operands = (" " + operands)
yield f"{blob_prefix}{name}{specifiers}{operands}"
if blob_suffix: