power_enums: provide selector type property
[openpower-isa.git] / src / openpower / decoder / power_enums.py
index 96158802cc500ee1f292112efa354016c81a1591..66298f989b669b5c59cf913e7aadd9081e774389 100644 (file)
@@ -71,21 +71,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)
@@ -170,11 +167,17 @@ class Form(Enum):
     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,28 +186,45 @@ 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):
         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):
+        return self.name
+
+
+@unique
+class SVMaskSrc(Enum):
+    NO = 0
+    EN = 1
 
     def __repr__(self):
         return self.name
@@ -221,24 +241,18 @@ class SVExtra(Enum):
 
     def __repr__(self):
         return {
-            SVExtra.NONE: "NONE",
-            SVExtra.Idx0: "[0]",
-            SVExtra.Idx1: "[1]",
-            SVExtra.Idx2: "[2]",
-            SVExtra.Idx3: "[3]",
-            SVExtra.Idx_1_2: "[1:2]",
+            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):
     NONE = auto()
     RA = auto()
@@ -266,16 +280,45 @@ class SVExtraReg(Enum):
     BFT = auto()
     WHOLE_REG = auto()
     SPR = auto()
+    RSp = auto()
+    RTp = auto()
+    FRAp = auto()
+    FRBp = auto()
+    FRSp = auto()
+    FRTp = auto()
 
     @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 = {
+            SVExtraReg.RSp: SVExtraReg.RS,
+            SVExtraReg.RTp: SVExtraReg.RT,
+            SVExtraReg.FRAp: SVExtraReg.FRA,
+            SVExtraReg.FRBp: SVExtraReg.FRB,
+            SVExtraReg.FRSp: SVExtraReg.FRS,
+            SVExtraReg.FRTp: SVExtraReg.FRT,
+        }.get(self)
+        if alias is not None:
+            return alias
+
+        alias = {
+            SVExtraReg.RA_OR_ZERO: SVExtraReg.RA,
+            SVExtraReg.RT_OR_ZERO: SVExtraReg.RT,
+        }.get(self)
+        if alias is not None:
+            return alias
+
+        return self
 
 
 @unique
@@ -283,30 +326,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 +520,6 @@ class SVP64RMMode(Enum):
     MAPREDUCE = 1
     FFIRST = 2
     SATURATE = 3
-    PREDRES = 4
     BRANCH = 5
 
 
@@ -348,23 +552,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,25 +607,110 @@ 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
+
+    @classmethod
+    def _missing_(cls, value):
+        if isinstance(value, SVExtraReg):
+            return cls.__members__.get(value.name)
+
+        return super()._missing_(value)
 
-    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
+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",
+    # fmin*/fmax* need to be replaced with fminmax
+    # https://bugs.libre-soc.org/show_bug.cgi?id=1057
+    # commented for now to make space for fmv/cvt
+    # "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",
+    "fmod", "fmods",
+    "fremainder", "fremainders",
+)
 
 
 # supported instructions: make sure to keep up-to-date with CSV files
@@ -411,6 +719,7 @@ _insns = [
     "NONE", "add", "addc", "addco", "adde", "addeo",
     "addi", "addic", "addic.", "addis",
     "addme", "addmeo", "addo", "addze", "addzeo",
+    "addex",
     "addg6s",
     "and", "andc", "andi.", "andis.",
     "attn",
@@ -430,8 +739,11 @@ _insns = [
     "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
@@ -442,9 +754,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
+    "fcvttg", "fcvttgo", "fcvttgs", "fcvttgso",
+    "fmvtg", "fmvtgs",
+    "fcvtfg", "fcvtfgs",
+    "fmvfg", "fmvfgs",
     'grev', 'grev.', 'grevi', 'grevi.',
     'grevw', 'grevw.', 'grevwi', 'grevwi.',
     "hrfid", "icbi", "icbt", "isel", "isync",
@@ -462,10 +777,13 @@ _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
     "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",
@@ -473,6 +791,7 @@ _insns = [
     "nand", "neg", "nego",
     "nop",
     "nor", "or", "orc", "ori", "oris",
+    "pcdec",
     "popcntb", "popcntd", "popcntw",
     "prtyd", "prtyw",
     "rfid",
@@ -486,6 +805,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",
@@ -503,6 +823,7 @@ _insns = [
     "tw", "twi",
     "wait",
     "xor", "xori", "xoris",
+    *FPTRANS_INSNS,
 ]
 
 # two-way lookup of instruction-to-index and vice-versa
@@ -615,21 +936,51 @@ 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
+
+
+class SelType(Enum):
+    NONE = None
+    SRC = 's'
+    DST = 'd'
+
+    def __repr__(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
+
+    @property
+    def type(self):
+        if self is In1Sel.NONE:
+            return SelType.NONE
+        return SelType.SRC
 
 
-@unique
 class In2Sel(Enum):
     NONE = 0
     RB = 1
@@ -645,33 +996,62 @@ 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
     CONST_DXHI4 = 18 # for addpcis
+    CONST_DQ = 19 # for ld/st-quad
+
+    @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
+
+    @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
+
+    @property
+    def type(self):
+        if self is OutSel.NONE:
+            return SelType.NONE
+        return SelType.DST
 
 
 @unique
@@ -707,7 +1087,7 @@ class CryIn(Enum):
     ZERO = 0
     ONE = 1
     CA = 2
-    # TODO OV = 3
+    OV = 3
 
 
 @unique
@@ -722,11 +1102,24 @@ class CRInSel(Enum):
     CR1 = 7
     BA = 8
 
+    @property
+    def type(self):
+        if self is CRInSel.NONE:
+            return SelType.NONE
+        return SelType.SRC
+
+
 @unique
 class CRIn2Sel(Enum):
     NONE = 0
     BB = 1
 
+    @property
+    def type(self):
+        if self is CRIn2Sel.NONE:
+            return SelType.NONE
+        return SelType.SRC
+
 
 @unique
 class CROutSel(Enum):
@@ -737,6 +1130,12 @@ class CROutSel(Enum):
     WHOLE_REG = 4
     CR1 = 5
 
+    @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
@@ -788,6 +1187,23 @@ 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',
+)
+
 if __name__ == '__main__':
     # find out what the heck is in SPR enum :)
     print("sprs full", len(SPRfull))