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 {
class NormalLDSTBaseRM(BaseRM):
- @property
- def specifiers(self):
- width = {
+ def specifiers(self, record):
+ widths = {
0b11: "8",
0b10: "16",
0b01: "32",
}
+ predicates = {
+ # integer
+ (0, 0b001): "1<<r3",
+ (0, 0b010): "r3",
+ (0, 0b011): "~r3",
+ (0, 0b100): "r10",
+ (0, 0b101): "~r10",
+ (0, 0b110): "r30",
+ (0, 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",
+ }
+
+ mmode = int(self.mmode)
+ mask = int(self.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={width[dw]}"
+ if all((dw, sw)) and (dw == sw):
+ yield f"w={widths[dw]}"
else:
if dw != 0b00:
- yield f"dw={width[dw]}"
+ yield f"dw={widths[dw]}"
if sw != 0b00:
- yield f"sw={width[sw]}"
+ yield f"sw={widths[sw]}"
- yield from super().specifiers
+ yield from super().specifiers(record=record)
class NormalBaseRM(NormalLDSTBaseRM):
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 NormalScalarReduceRM(NormalBaseRM):
"""normal: scalar reduce mode (mapreduce), SUBVL=1"""
RG: BaseRM.mode[4]
+ def specifiers(self, record):
+ if self.RG:
+ yield "mrr"
-class NormalSubvectorReduceRM(NormalBaseRM):
- """normal: subvector reduce mode, SUBVL>1"""
- SVM: BaseRM.mode[3]
-
- @property
- def specifiers(self):
- if self.SVM:
- yield "svm"
-
- yield from super().specifiers
+ yield from super().specifiers(record=record)
class NormalReservedRM(NormalBaseRM):
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"""
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 "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):
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
- svmr: NormalSubvectorReduceRM
reserved: NormalReservedRM
ffrc1: NormalFailFirstRc1RM
ffrc0: NormalFailFirstRc0RM
sat: NormalSaturationRM
- satx: NormalSaturationExtRM
prrc1: NormalPredResultRc1RM
prrc0: NormalPredResultRc0RM
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):
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"""
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):
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
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):
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):
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 "sats"
else:
yield "satu"
- yield from super().specifiers
+
+ yield from super().specifiers(record=record)
class LDSTIdxPredResultRc1RM(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):
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):
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"
- if self.SVM:
- yield "svm"
-
- yield from super().specifiers
+ yield from super().specifiers(record=record)
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):
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):
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
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 == 1:
- rm = rm.smr
- elif self.subvl > 1:
- rm = rm.svmr
- else:
- rm = rm.reserved
- 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
- 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.reserved
- 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 == 1:
- rm = rm.smr
- elif self.subvl > 1:
- 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)
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 = ""