def get_csv(name):
+ retval = _get_csv(name)
+ return [i.copy() for i in retval]
+
+
+@functools.lru_cache()
+def _get_csv(name):
"""gets a not-entirely-csv-file-formatted database, which allows comments
"""
file_path = find_wiki_file(name)
class Enum(_Enum):
@classmethod
- def _missing_(cls, value):
- if isinstance(value, str):
+ def _missing_(cls, desc):
+ if isinstance(desc, str):
try:
- if value == "":
- value = 0
+ if desc == "":
+ desc = 0
else:
- value = int(value, 0)
+ desc = int(desc, 0)
except ValueError:
pass
keys = {item.name:item for item in cls}
- values = {item.value:item for item in cls}
- item = keys.get(value, values.get(value))
- if item is None:
- raise ValueError(value)
- return item
+ descs = {item.value:item for item in cls}
+ return keys.get(desc, descs.get(desc))
# this corresponds to which Function Unit (pipeline-with-Reservation-Stations)
SVM2 = 33 # Simple-V SHAPE2 mode - fits into SVM
SVRM = 34 # Simple-V REMAP mode
TLI = 35 # ternlogi
- XB = 36
+ # 36 available
BM2 = 37 # bmask
SVI = 38 # Simple-V Index Mode
VA2 = 39
SVC = 40
SVR = 41
+ CRB = 42 # crternlogi / crbinlut
+ MM = 43 # [f]minmax[s][.]
+ CW = 44
+ CW2 = 45
+ DCT = 46 # fdmadds
# Simple-V svp64 fields https://libre-soc.org/openpower/sv/svp64/
@unique
-class SVPtype(Enum):
+class SVPType(Enum):
NONE = 0
P1 = 1
P2 = 2
+ P2M = 3 # for mixed EXTRA3/3/2 where MASK_SRC is RM[6,7,18]
@classmethod
- def _missing_(cls, value):
- return {"1P": SVPtype.P1, "2P": SVPtype.P2}[value]
+ def _missing_(cls, desc):
+ return {"1P": SVPType.P1, "2P": SVPType.P2, "2PM": SVPType.P2M}.get(desc)
- def __repr__(self):
+ def __str__(self):
return {
- SVPtype.NONE: "NONE",
- SVPtype.P1: "1P",
- SVPtype.P2: "2P",
+ SVPType.NONE: "NONE",
+ SVPType.P1: "1P",
+ SVPType.P2: "2P",
+ SVPType.P2M: "2PM",
}[self]
@unique
-class SVEtype(Enum):
+class SVEType(Enum):
+ """SVEType
+ * EXTRA2 : 0: [10,11] 1: [12,13] 2: [14,15] 3: [16,17] unused: [18]
+ * EXTRA3 : 0: [10,11,12] 1: [13,14,15] mask: [16,17,18]
+ * EXTRA32: 0: [10,11,12] 1: [13,14,15] 2: [16,17] mask: [6,7,18]
+ """
NONE = 0
EXTRA2 = 1
EXTRA3 = 2
+ EXTRA32 = 3 # mixed EXTRA3 and EXTRA2 using RM bits 6&7 for MASK_SRC
- def __repr__(self):
+ def __str__(self):
return self.name
@unique
-class SVmask_src(Enum):
+class SVMaskSrc(Enum):
NO = 0
EN = 1
- def __repr__(self):
+ def __str__(self):
return self.name
Idx3 = 4
Idx_1_2 = 5 # due to weird BA/BB for crops
- def __repr__(self):
+ def __str__(self):
return {
SVExtra.NONE: "NONE",
- SVExtra.Idx0: "[0]",
- SVExtra.Idx1: "[1]",
- SVExtra.Idx2: "[2]",
- SVExtra.Idx3: "[3]",
- SVExtra.Idx_1_2: "[1:2]",
+ SVExtra.Idx0: "EXTRA0",
+ SVExtra.Idx1: "EXTRA1",
+ SVExtra.Idx2: "EXTRA2",
+ SVExtra.Idx3: "EXTRA3",
+ SVExtra.Idx_1_2: "EXTRA1/EXTRA2",
}[self]
# Backward compatibility
SVEXTRA = SVExtra
-class SVExtraRegType(Enum):
- NONE = None
- SRC = 's'
- DST = 'd'
-
-
-class SVExtraReg(Enum):
+class Reg(Enum):
NONE = auto()
RA = auto()
- RA_OR_ZERO = RA
+ RA_OR_ZERO = auto()
RB = auto()
RC = auto()
RS = auto()
RT = auto()
- RT_OR_ZERO = RT
+ RT_OR_ZERO = auto()
FRA = auto()
FRB = auto()
FRC = auto()
BFT = auto()
WHOLE_REG = auto()
SPR = auto()
+ RSp = auto()
+ RTp = auto()
+ FRAp = auto()
+ FRBp = auto()
+ FRSp = auto()
+ FRTp = auto()
+
+ def __str__(self):
+ return self.name
@classmethod
- def _missing_(cls, value):
+ def _missing_(cls, desc):
selectors = (
In1Sel, In2Sel, In3Sel, CRInSel, CRIn2Sel,
OutSel, CROutSel,
)
- if isinstance(value, selectors):
- return cls.__members__[value.name]
- return super()._missing_(value)
+ if isinstance(desc, selectors):
+ return cls.__members__.get(desc.name)
+
+ return cls.__members__.get(desc)
+
+ @property
+ def alias(self):
+ alias = {
+ Reg.RSp: Reg.RS,
+ Reg.RTp: Reg.RT,
+ Reg.FRAp: Reg.FRA,
+ Reg.FRBp: Reg.FRB,
+ Reg.FRSp: Reg.FRS,
+ Reg.FRTp: Reg.FRT,
+ }.get(self)
+ if alias is not None:
+ return alias
+
+ alias = {
+ Reg.RA_OR_ZERO: Reg.RA,
+ Reg.RT_OR_ZERO: Reg.RT,
+ }.get(self)
+ if alias is not None:
+ return alias
+
+ return self
+
+ @property
+ def or_zero(self):
+ return (self in (
+ Reg.RA_OR_ZERO,
+ Reg.RT_OR_ZERO,
+ ))
+
+ @property
+ def pair(self):
+ return (self in (
+ Reg.RSp,
+ Reg.RTp,
+ Reg.FRAp,
+ Reg.FRBp,
+ Reg.FRSp,
+ Reg.FRTp,
+ ))
@unique
ALWAYS = 0
INT = 1
CR = 2
+ RC1 = 3
@unique
class SVP64PredInt(Enum):
- ALWAYS = 0
- R3_UNARY = 1
- R3 = 2
- R3_N = 3
- R10 = 4
- R10_N = 5
- R30 = 6
- R30_N = 7
+ ALWAYS = 0b000
+ R3_UNARY = 0b001
+ R3 = 0b010
+ R3_N = 0b011
+ R10 = 0b100
+ R10_N = 0b101
+ R30 = 0b110
+ R30_N = 0b111
+
+ @classmethod
+ def _missing_(cls, desc):
+ if isinstance(desc, str):
+ value = desc
+ values = {
+ "^r3": cls.R3_UNARY,
+ "r3": cls.R3,
+ "~r3": cls.R3_N,
+ "r10": cls.R10,
+ "~r10": cls.R10_N,
+ "r30": cls.R30,
+ "~r30": cls.R30_N,
+ }
+ if value.startswith("~"):
+ value = f"~{value[1:].strip()}"
+ elif "<<" in value: # 1 << r3
+ (lhs, _, rhs) = value.partition("<<")
+ lhs = lhs.strip().lower()
+ rhs = rhs.strip().lower()
+ if (lhs == "1") and (rhs in ("r3", "%r3")):
+ value = "^r3"
+
+ return values.get(value)
+
+ return super()._missing_(desc)
+
+ def __str__(self):
+ return {
+ self.__class__.ALWAYS: "",
+ self.__class__.R3_UNARY: "^r3",
+ self.__class__.R3: "r3",
+ self.__class__.R3_N: "~r3",
+ self.__class__.R10: "r10",
+ self.__class__.R10_N: "~r10",
+ self.__class__.R30: "r30",
+ self.__class__.R30_N: "~r30",
+ }[self]
+
+ def __repr__(self):
+ return f"{self.__class__.__name__}({str(self)})"
+
+ def __int__(self):
+ return self.value
+
+ @property
+ def mode(self):
+ return SVP64PredMode.INT
+
+ @property
+ def inv(self):
+ return (self.value & 0b1)
+
+ @property
+ def state(self):
+ return (self.value >> 1)
-@unique
class SVP64PredCR(Enum):
LT = 0
GE = 1
+ NL = GE
GT = 2
LE = 3
+ NG = LE
EQ = 4
NE = 5
SO = 6
+ UN = SO
NS = 7
+ NU = NS
+
+ @classmethod
+ def _missing_(cls, desc):
+ if isinstance(desc, str):
+ name = desc.upper()
+ return cls.__members__.get(name)
+
+ return super()._missing_(desc)
+
+ def __int__(self):
+ return self.value
+
+ @property
+ def mode(self):
+ return SVP64PredMode.CR
+
+ @property
+ def inv(self):
+ return (self.value & 0b1)
+
+ @property
+ def state(self):
+ return (self.value >> 1)
+
+
+@unique
+class SVP64PredRC1(Enum):
+ RC1 = 0
+ RC1_N = 1
+
+ @classmethod
+ def _missing_(cls, desc):
+ return {
+ "RC1": SVP64PredRC1.RC1,
+ "~RC1": SVP64PredRC1.RC1_N,
+ }.get(desc)
+
+ def __int__(self):
+ return 1
+
+ @property
+ def mode(self):
+ return SVP64PredMode.RC1
+
+ @property
+ def inv(self):
+ return (self is SVP64PredRC1.RC1_N)
+
+ @property
+ def state(self):
+ return 1
+
+
+class SVP64Pred(Enum):
+ ALWAYS = SVP64PredInt.ALWAYS
+ R3_UNARY = SVP64PredInt.R3_UNARY
+ R3 = SVP64PredInt.R3
+ R3_N = SVP64PredInt.R3_N
+ R10 = SVP64PredInt.R10
+ R10_N = SVP64PredInt.R10_N
+ R30 = SVP64PredInt.R30
+ R30_N = SVP64PredInt.R30_N
+
+ LT = SVP64PredCR.LT
+ GE = SVP64PredCR.GE
+ GT = SVP64PredCR.GT
+ LE = SVP64PredCR.LE
+ EQ = SVP64PredCR.EQ
+ NE = SVP64PredCR.NE
+ SO = SVP64PredCR.SO
+ NS = SVP64PredCR.NS
+
+ RC1 = SVP64PredRC1.RC1
+ RC1_N = SVP64PredRC1.RC1_N
+
+ @classmethod
+ def _missing_(cls, desc):
+ if isinstance(desc, str):
+ values = {item.value:item for item in cls}
+ for subcls in (SVP64PredInt, SVP64PredCR, SVP64PredRC1):
+ try:
+ return values.get(subcls(desc))
+ except ValueError:
+ pass
+ return None
+
+ return super()._missing_(desc)
+
+ def __int__(self):
+ return int(self.value)
+
+ @property
+ def mode(self):
+ return self.value.mode
+
+ @property
+ def inv(self):
+ return self.value.inv
+
+ @property
+ def state(self):
+ return self.value.state
@unique
MAPREDUCE = 1
FFIRST = 2
SATURATE = 3
- PREDRES = 4
BRANCH = 5
@unique
-class SVP64width(Enum):
+class SVP64Width(Enum):
DEFAULT = 0
EW_32 = 1
EW_16 = 2
EW_8 = 3
+ @classmethod
+ def _missing_(cls, desc):
+ if isinstance(desc, str):
+ return {
+ "32": SVP64Width.EW_32,
+ "16": SVP64Width.EW_16,
+ "8": SVP64Width.EW_8,
+ }.get(desc)
+
+ return super()._missing_(desc)
+
@unique
-class SVP64subvl(Enum):
+class SVP64SubVL(Enum):
VEC1 = 0
VEC2 = 1
VEC3 = 2
VEC4 = 3
+ @classmethod
+ def _missing_(cls, desc):
+ if isinstance(desc, str):
+ name = desc.upper()
+ return cls.__members__.get(name)
+
+ return super()._missing_(desc)
+
@unique
-class SVP64sat(Enum):
+class SVP64Sat(Enum):
NONE = 0
SIGNED = 1
UNSIGNED = 2
RB = GPR
RC = GPR
RS = GPR
+ RSp = RS
RT = GPR
+ RTp = RT
FPR = 1
FRA = FPR
+ FRAp = FRA
FRB = FPR
+ FRBp = FRB
FRC = FPR
FRS = FPR
+ FRSp = FRS
FRT = FPR
+ FRTp = FRT
- CR_REG = 2 # actually CR Field. the CR register is 32-bit.
- BF = CR_REG
- BFA = CR_REG
+ CR_3BIT = 2 # CR field; the CR register is 32-bit
+ BF = CR_3BIT
+ BFA = CR_3BIT
- CR_BIT = 3 # refers to one bit of the 32-bit CR register
- BA = CR_BIT
- BB = CR_BIT
- BC = CR_BIT
- BI = CR_BIT
- BT = CR_BIT
+ CR_5BIT = 3 # bit of the 32-bit CR register
+ BA = CR_5BIT
+ BB = CR_5BIT
+ BC = CR_5BIT
+ BI = CR_5BIT
+ BT = CR_5BIT
XER_BIT = 4 # XER bits, includes OV, OV32, SO, CA, CA32
OV = XER_BIT
@classmethod
def _missing_(cls, value):
- if isinstance(value, SVExtraReg):
- return cls.__members__[value.name]
+ if isinstance(value, Reg):
+ return cls.__members__.get(value.name)
+
return super()._missing_(value)
"fasinh", "fasinhs",
"facosh", "facoshs",
"fatanh", "fatanhs",
- "fminnum08", "fminnum08s",
- "fmaxnum08", "fmaxnum08s",
- "fmin19", "fmin19s",
- "fmax19", "fmax19s",
- "fminnum19", "fminnum19s",
- "fmaxnum19", "fmaxnum19s",
- "fminc", "fmincs",
- "fmaxc", "fmaxcs",
- "fminmagnum08", "fminmagnum08s",
- "fmaxmagnum08", "fmaxmagnum08s",
- "fminmag19", "fminmag19s",
- "fmaxmag19", "fmaxmag19s",
- "fminmagnum19", "fminmagnum19s",
- "fmaxmagnum19", "fmaxmagnum19s",
- "fminmagc", "fminmagcs",
- "fmaxmagc", "fmaxmagcs",
+ "fminmax",
"fmod", "fmods",
"fremainder", "fremainders",
)
"NONE", "add", "addc", "addco", "adde", "addeo",
"addi", "addic", "addic.", "addis",
"addme", "addmeo", "addo", "addze", "addzeo",
+ "addex",
"addg6s",
"and", "andc", "andi.", "andis.",
"attn",
"absdacs", "absdacu", # AV bitmanip
"avgadd", # AV bitmanip
"b", "bc", "bcctr", "bclr", "bctar",
+ "brh", "brw", "brd",
"bmask", # AV bitmanip
"bpermd",
"cbcdtd",
"cdtbcd",
+ "cfuged",
"cmp", "cmpb", "cmpeqb", "cmpi", "cmpl", "cmpli", "cmprb",
- "cntlzd", "cntlzw", "cnttzd", "cnttzw",
+ "cntlzd", "cntlzdm", "cntlzw", "cnttzd", "cnttzdm", "cnttzw",
"cprop", # AV bitmanip
"crand", "crandc", "creqv",
"crnand", "crnor", "cror", "crorc", "crxor",
"divmod2du",
"divw", "divwe", "divweo",
"divweu", "divweuo", "divwo", "divwu", "divwuo",
- "dsld", "dsrd",
+ "dsld", "dsld.", "dsrd", "dsrd.",
"eieio", "eqv",
"extsb", "extsh", "extsw", "extswsli",
"fadd", "fadds", "fsub", "fsubs", # FP add / sub
"fmr", "fabs", "fnabs", "fneg", "fcpsgn", # FP move/abs/neg
"fmvis", # FP load immediate
"fishmv", # Float Replace Lower-Half Single, Immediate
- 'grev', 'grev.', 'grevi', 'grevi.',
- 'grevw', 'grevw.', 'grevwi', 'grevwi.',
+ "cffpr", "cffpro",
+ "mffpr", "mffprs",
+ "ctfpr", "ctfprs",
+ "mtfpr", "mtfprs",
"hrfid", "icbi", "icbt", "isel", "isync",
"lbarx", "lbz", "lbzcix", "lbzu", "lbzux", "lbzx", # load byte
"ld", "ldarx", "ldbrx", "ldu", "ldux", "ldx", # load double
"lwz", "lwzcix", "lwzu", "lwzux", "lwzx", # more load word
# "lwabr", # load word SVP64 bit-reversed
# "lwzbr", "lwzubr", # more load word SVP64 bit-reversed
- "maddedu",
+ "maddedu", "maddedus",
"maddhd", "maddhdu", "maddld", # INT multiply-and-add
+ "maddsubrs", # Integer DCT Butterfly Add Sub and Round Shift
+ "maddrs", # Integer DCT Butterfly Add and Accumulate and Round Shift
+ "msubrs", # Integer DCT Butterfly Subtract from and Round Shift
"mcrf", "mcrxr", "mcrxrx", "mfcr/mfocrf", # CR mvs
"mfmsr", "mfspr",
- "mins", "maxs", "minu", "maxu", # AV bitmanip
+ "minmax", # AV bitmanip
"modsd", "modsw", "modud", "moduw",
"mtcrf/mtocrf", "mtmsr", "mtmsrd", "mtspr",
"mulhd", "mulhdu", "mulhw", "mulhwu", "mulld", "mulldo",
"nop",
"nor", "or", "orc", "ori", "oris",
"pcdec",
+ "pdepd", "pextd",
"popcntb", "popcntd", "popcntw",
"prtyd", "prtyw",
"rfid",
"rldcl", "rldcr", "rldic", "rldicl", "rldicr", "rldimi",
"rlwimi", "rlwinm", "rlwnm",
"setb",
+ "setbc", "setbcr", "setnbc", "setnbcr",
"setvl", # https://libre-soc.org/openpower/sv/setvl
"svindex", # https://libre-soc.org/openpower/sv/remap
"svremap", # https://libre-soc.org/openpower/sv/remap - TEMPORARY
"svshape2", # https://libre-soc.org/openpower/sv/remap/discussion TODO
"svstep", # https://libre-soc.org/openpower/sv/setvl
"sim_cfg",
+ "sadd", "saddw", "sadduw",
"slbia", "sld", "slw", "srad", "sradi",
"sraw", "srawi", "srd", "srw",
"stb", "stbcix", "stbcx", "stbu", "stbux", "stbx",
OP_CBCDTD = 85
OP_TERNLOG = 86
OP_FETCH_FAILED = 87
- OP_GREV = 88
+ # 88 available
OP_MINMAX = 89
OP_AVGADD = 90
OP_ABSDIFF = 91
OP_DIVMOD2DU = 100
OP_DSHL = 101
OP_DSHR = 102
+ OP_SHADD = 103
+ OP_MADDSUBRS = 104
+ OP_MADDRS = 105
+ OP_MSUBRS = 106
+ OP_BYTEREV = 107
+ OP_CFUGE = 108
+ OP_PDEP = 109
+ OP_PEXT = 110
+ OP_SETBC = 111
+
+
+class SelType(Enum):
+ NONE = None
+ SRC = 's'
+ DST = 'd'
+
+ def __str__(self):
+ return {
+ SelType.NONE: "NONE",
+ SelType.SRC: "SRC",
+ SelType.DST: "DST",
+ }[self]
-@unique
class In1Sel(Enum):
NONE = 0
RA = 1
RA_OR_ZERO = 2
SPR = 3
RS = 4 # for some ALU/Logical operations
+ RSp = RS
FRA = 5
+ FRAp = FRA
FRS = 6
- CIA = 7 # for addpcis
+ FRSp = FRS
+ FRT = 7
+ CIA = 8 # for addpcis
+ RT = 9
+
+ def __str__(self):
+ if self is In1Sel.RA_OR_ZERO:
+ return "RA0"
+ return self.name
+
+ @property
+ def type(self):
+ if self is In1Sel.NONE:
+ return SelType.NONE
+ return SelType.SRC
-@unique
class In2Sel(Enum):
NONE = 0
RB = 1
CONST_SH32 = 11
SPR = 12
RS = 13 # for shiftrot (M-Form)
+ RSp = RS
FRB = 14
+ FRBp = FRB
CONST_SVD = 15 # for SVD-Form
CONST_SVDS = 16 # for SVDS-Form
- CONST_XBI = 17
+ # 17 available
CONST_DXHI4 = 18 # for addpcis
CONST_DQ = 19 # for ld/st-quad
+ def __str__(self):
+ return self.name
+
+ @property
+ def type(self):
+ if self is In2Sel.NONE:
+ return SelType.NONE
+ return SelType.SRC
+
-@unique
class In3Sel(Enum):
NONE = 0
RS = 1
+ RSp = RS
RB = 2 # for shiftrot (M-Form)
FRS = 3
+ FRSp = FRS
FRC = 4
RC = 5 # for SVP64 bit-reverse LD/ST
RT = 6 # for ternlog[i]
+ RTp = RT
+ FRA = 7
+
+ def __str__(self):
+ return self.name
+
+ @property
+ def type(self):
+ if self is In3Sel.NONE:
+ return SelType.NONE
+ return SelType.SRC
-@unique
class OutSel(Enum):
NONE = 0
RT = 1
+ RTp = RT
RA = 2
SPR = 3
RT_OR_ZERO = 4
FRT = 5
+ FRTp = FRT
FRS = 6
+ FRSp = FRS
RS = 7
+ RSp = RS
+ FRA = 8
+
+ def __str__(self):
+ if self is OutSel.RT_OR_ZERO:
+ return "RT0"
+ return self.name
+
+ @property
+ def type(self):
+ if self is OutSel.NONE:
+ return SelType.NONE
+ return SelType.DST
@unique
CR1 = 7
BA = 8
+ def __str__(self):
+ return self.name
+
+ @property
+ def type(self):
+ if self is CRInSel.NONE:
+ return SelType.NONE
+ return SelType.SRC
+
@unique
class CRIn2Sel(Enum):
NONE = 0
BB = 1
+ def __str__(self):
+ return self.name
+
+ @property
+ def type(self):
+ if self is CRIn2Sel.NONE:
+ return SelType.NONE
+ return SelType.SRC
+
@unique
class CROutSel(Enum):
WHOLE_REG = 4
CR1 = 5
+ def __str__(self):
+ return self.name
+
+ @property
+ def type(self):
+ if self is CROutSel.NONE:
+ return SelType.NONE
+ return SelType.DST
+
# SPRs - Special-Purpose Registers. See V3.0B Figure 18 p971 and
# http://libre-riscv.org/openpower/isatables/sprs.csv
MSRSpec = namedtuple("MSRSpec", ["dr", "pr", "sf"])
+# flags for bfp_* functions
+BFP_FLAG_NAMES = (
+ 'vxsnan_flag',
+ 'vximz_flag',
+ 'vxidi_flag',
+ 'vxisi_flag',
+ 'vxzdz_flag',
+ 'vxsqrt_flag',
+ 'vxcvi_flag',
+ 'vxvc_flag',
+ 'ox_flag',
+ 'ux_flag',
+ 'xx_flag',
+ 'zx_flag',
+ 'inc_flag',
+)
+
+
+@unique
+class FMinMaxMode(Enum):
+ """ FMM field for fminmax instruction.
+ enumerant names match assembly aliases.
+ """
+ fminnum08 = 0b0000
+ fmin19 = 0b0001
+ fminnum19 = 0b0010
+ fminc = 0b0011
+ fminmagnum08 = 0b0100
+ fminmag19 = 0b0101
+ fminmagnum19 = 0b0110
+ fminmagc = 0b0111
+ fmaxnum08 = 0b1000
+ fmax19 = 0b1001
+ fmaxnum19 = 0b1010
+ fmaxc = 0b1011
+ fmaxmagnum08 = 0b1100
+ fmaxmag19 = 0b1101
+ fmaxmagnum19 = 0b1110
+ fmaxmagc = 0b1111
+
if __name__ == '__main__':
# find out what the heck is in SPR enum :)
print("sprs full", len(SPRfull))