remove grev, leaving unit tests for later use by grevlut
[openpower-isa.git] / src / openpower / decoder / power_enums.py
index 3dacbd13e19c55b83a3c8a488159c9288f6d8ad0..54e325ae64fb823a373901606c65e68ed1aa1976 100644 (file)
@@ -40,6 +40,12 @@ def find_wiki_file(name):
 
 
 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)
@@ -71,21 +77,18 @@ def get_signal_name(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)
@@ -160,42 +163,77 @@ class Form(Enum):
     SVL = 29  # Simple-V for setvl instruction
     SVD = 30  # Simple-V for LD/ST bit-reverse, variant of D-Form
     SVDS = 31  # Simple-V for LD/ST bit-reverse, variant of DS-Form
-    SVM = 32  # Simple-V SHAPE mode - TEMPORARY TEMPORARY TEMPORARY
-    SVRM = 33  # Simple-V REMAP mode
-    TLI = 34  # ternlogi
-    XB = 35
-    BM2 = 36 # bmask
-    SVI = 37  # Simple-V Index Mode
-    VA2 = 38
-    SVC = 39
-    SVR = 40
+    SVM = 32  # Simple-V SHAPE mode
+    SVM2 = 33  # Simple-V SHAPE2 mode - fits into SVM
+    SVRM = 34  # Simple-V REMAP mode
+    TLI = 35  # ternlogi
+    # 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/
 
 
 class SVMode(Enum):
+    NONE = 0          # for non-SV instructions only
     NORMAL = auto()
-    LDST = auto()
+    LDST_IDX = auto()
+    LDST_IMM = auto()
     BRANCH = auto()
     CROP = auto()
 
 
 @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 __str__(self):
+        return {
+            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 __str__(self):
+        return self.name
+
+
+@unique
+class SVMaskSrc(Enum):
+    NO = 0
+    EN = 1
+
+    def __str__(self):
+        return self.name
 
 
 @unique
@@ -207,25 +245,29 @@ class SVExtra(Enum):
     Idx3 = 4
     Idx_1_2 = 5  # due to weird BA/BB for crops
 
+    def __str__(self):
+        return {
+            SVExtra.NONE: "NONE",
+            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()
@@ -244,16 +286,66 @@ class SVExtraReg(Enum):
     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,
+            In1Sel, In2Sel, In3Sel, CRInSel, CRIn2Sel,
             OutSel, CROutSel,
         )
-        if isinstance(value, selectors):
-            return cls.__members__.get(value.name, cls.NONE)
-        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
@@ -261,30 +353,192 @@ class SVP64PredMode(Enum):
     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
@@ -293,7 +547,6 @@ class SVP64RMMode(Enum):
     MAPREDUCE = 1
     FFIRST = 2
     SATURATE = 3
-    PREDRES = 4
     BRANCH = 5
 
 
@@ -326,23 +579,42 @@ class SVP64BCCTRMode(Enum):
 
 
 @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
@@ -362,26 +634,92 @@ class RegType(Enum):
     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_3BIT = 2 # CR field; the CR register is 32-bit
+    BF = CR_3BIT
+    BFA = CR_3BIT
+
+    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
+    OV32 = XER_BIT
+    CA = XER_BIT
+    CA32 = XER_BIT
+    SO = XER_BIT
 
-    CR_REG = 2
-    BF = CR_REG
-    BFA = CR_REG
+    @classmethod
+    def _missing_(cls, value):
+        if isinstance(value, Reg):
+            return cls.__members__.get(value.name)
 
-    CR_BIT = 3
-    BA = CR_BIT
-    BB = CR_BIT
-    BC = CR_BIT
-    BI = CR_BIT
-    BT = CR_BIT
-    BFT = CR_BIT
+        return super()._missing_(value)
+
+
+FPTRANS_INSNS = (
+    "fatan2", "fatan2s",
+    "fatan2pi", "fatan2pis",
+    "fpow", "fpows",
+    "fpown", "fpowns",
+    "fpowr", "fpowrs",
+    "frootn", "frootns",
+    "fhypot", "fhypots",
+    "frsqrt", "frsqrts",
+    "fcbrt", "fcbrts",
+    "frecip", "frecips",
+    "fexp2m1", "fexp2m1s",
+    "flog2p1", "flog2p1s",
+    "fexp2", "fexp2s",
+    "flog2", "flog2s",
+    "fexpm1", "fexpm1s",
+    "flogp1", "flogp1s",
+    "fexp", "fexps",
+    "flog", "flogs",
+    "fexp10m1", "fexp10m1s",
+    "flog10p1", "flog10p1s",
+    "fexp10", "fexp10s",
+    "flog10", "flog10s",
+    "fsin", "fsins",
+    "fcos", "fcoss",
+    "ftan", "ftans",
+    "fasin", "fasins",
+    "facos", "facoss",
+    "fatan", "fatans",
+    "fsinpi", "fsinpis",
+    "fcospi", "fcospis",
+    "ftanpi", "ftanpis",
+    "fasinpi", "fasinpis",
+    "facospi", "facospis",
+    "fatanpi", "fatanpis",
+    "fsinh", "fsinhs",
+    "fcosh", "fcoshs",
+    "ftanh", "ftanhs",
+    "fasinh", "fasinhs",
+    "facosh", "facoshs",
+    "fatanh", "fatanhs",
+    "fminmax",
+    "fmod", "fmods",
+    "fremainder", "fremainders",
+)
 
 
 # supported instructions: make sure to keep up-to-date with CSV files
@@ -390,6 +728,7 @@ _insns = [
     "NONE", "add", "addc", "addco", "adde", "addeo",
     "addi", "addic", "addic.", "addis",
     "addme", "addmeo", "addo", "addze", "addzeo",
+    "addex",
     "addg6s",
     "and", "andc", "andi.", "andis.",
     "attn",
@@ -397,20 +736,25 @@ _insns = [
     "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",
     "darn",
     "dcbf", "dcbst", "dcbt", "dcbtst", "dcbz",
     "divd", "divde", "divdeo", "divdeu",
-    "divdeuo", "divdo", "divdu", "divduo", "divw", "divwe", "divweo",
+    "divdeuo", "divdo", "divdu", "divduo",
+    "divmod2du",
+    "divw", "divwe", "divweo",
     "divweu", "divweuo", "divwo", "divwu", "divwuo",
+    "dsld", "dsld.", "dsrd", "dsrd.",
     "eieio", "eqv",
     "extsb", "extsh", "extsw", "extswsli",
     "fadd", "fadds", "fsub", "fsubs",                   # FP add / sub
@@ -421,11 +765,12 @@ _insns = [
     "ffmsubs", "ffmadds", "ffnmsubs", "ffnmadds",       # FFT FP 3-arg
     "fmul", "fmuls", "fdiv", "fdivs",                   # FP mul / div
     "fmr", "fabs", "fnabs", "fneg", "fcpsgn",           # FP move/abs/neg
-    "fsins", "fcoss",                                   # FP SIN/COS
     "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
@@ -441,10 +786,14 @@ _insns = [
     "lwz", "lwzcix", "lwzu", "lwzux", "lwzx",           # more load word
     # "lwabr",           # load word SVP64 bit-reversed
     # "lwzbr", "lwzubr", # more load word SVP64 bit-reversed
+    "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",
@@ -452,18 +801,23 @@ _insns = [
     "nand", "neg", "nego",
     "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
-    "svshape",  # https://libre-soc.org/openpower/sv/remap
+    "svshape",  # https://libre-soc.org/openpower/sv/remap/#svshape
+    "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",
@@ -481,6 +835,7 @@ _insns = [
     "tw", "twi",
     "wait",
     "xor", "xori", "xoris",
+    *FPTRANS_INSNS,
 ]
 
 # two-way lookup of instruction-to-index and vice-versa
@@ -583,7 +938,7 @@ class MicrOp(Enum):
     OP_CBCDTD = 85
     OP_TERNLOG = 86
     OP_FETCH_FAILED = 87
-    OP_GREV = 88
+    # 88 available
     OP_MINMAX = 89
     OP_AVGADD = 90
     OP_ABSDIFF = 91
@@ -593,20 +948,62 @@ class MicrOp(Enum):
     OP_SVINDEX = 95
     OP_FMVIS = 96
     OP_FISHMV = 97
+    OP_PCDEC = 98
+    OP_MADDEDU = 99
+    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
+    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
@@ -622,32 +1019,73 @@ class In2Sel(Enum):
     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
@@ -671,10 +1109,10 @@ class LDSTMode(Enum):
 
 
 @unique
-class RC(Enum):
+class RCOE(Enum):
     NONE = 0
     ONE = 1
-    RC_OE = 2    # includes OE
+    RC = 2    # includes OE
     RC_ONLY = 3  # does not include OE
 
 
@@ -683,7 +1121,7 @@ class CryIn(Enum):
     ZERO = 0
     ONE = 1
     CA = 2
-    # TODO OV = 3
+    OV = 3
 
 
 @unique
@@ -696,6 +1134,31 @@ class CRInSel(Enum):
     BC = 5
     WHOLE_REG = 6
     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
@@ -707,6 +1170,15 @@ 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
@@ -758,6 +1230,46 @@ XER_bits = {
 
 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))