remove grev, leaving unit tests for later use by grevlut
[openpower-isa.git] / src / openpower / decoder / power_enums.py
index 7af2e63e627d79e97646dbd335ad1c924bcf2162..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)
@@ -164,17 +167,23 @@ class Form(Enum):
     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/
 
 
 class SVMode(Enum):
+    NONE = 0          # for non-SV instructions only
     NORMAL = auto()
     LDST_IDX = auto()
     LDST_IMM = auto()
@@ -183,30 +192,47 @@ class SVMode(Enum):
 
 
 @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 SVMaskSrc(Enum):
+    NO = 0
+    EN = 1
+
+    def __str__(self):
         return self.name
 
 
@@ -219,35 +245,29 @@ class SVExtra(Enum):
     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()
@@ -266,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, 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
@@ -283,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
@@ -315,7 +547,6 @@ class SVP64RMMode(Enum):
     MAPREDUCE = 1
     FFIRST = 2
     SATURATE = 3
-    PREDRES = 4
     BRANCH = 5
 
 
@@ -348,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
@@ -384,30 +634,44 @@ 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
-
-    CR_REG = 2  # actually CR Field. the CR register is 32-bit.
-    BF = CR_REG
-    BFA = CR_REG
-
-    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
+    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
 
     @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)
 
 
@@ -452,22 +716,7 @@ FPTRANS_INSNS = (
     "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",
 )
@@ -479,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",
@@ -486,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
@@ -512,8 +767,10 @@ _insns = [
     "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
@@ -529,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",
@@ -540,12 +801,15 @@ _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
@@ -553,6 +817,7 @@ _insns = [
     "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",
@@ -673,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
@@ -683,21 +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
-    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
@@ -713,33 +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
@@ -775,7 +1121,7 @@ class CryIn(Enum):
     ZERO = 0
     ONE = 1
     CA = 2
-    # TODO OV = 3
+    OV = 3
 
 
 @unique
@@ -790,12 +1136,30 @@ class CRInSel(Enum):
     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):
@@ -806,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
@@ -857,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))