comments
[openpower-isa.git] / src / openpower / decoder / power_enums.py
index 477e472aae85b727db32f65e295f33523ab39800..2eef375801e3aee0badac50711507da07c787506 100644 (file)
@@ -1,4 +1,4 @@
-# SPDX-License: LGPLv3+
+# SPDX-License-Identifier: LGPL-3-or-later
 # Copyright (C) 2020, 2021 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
 # Copyright (C) 2020, Michael Nolan
 
@@ -14,11 +14,16 @@ regfile size in HDL.  this is SPRreduced and the supported list is in
 get_spr_enum
 """
 
-from enum import Enum, unique
+from enum import (
+    auto,
+    Enum as _Enum,
+    unique,
+)
 import csv
 import os
 from os.path import dirname, join
 from collections import namedtuple
+import functools
 
 
 def find_wiki_dir():
@@ -35,8 +40,11 @@ def find_wiki_file(name):
 
 
 def get_csv(name):
+    """gets a not-entirely-csv-file-formatted database, which allows comments
+    """
     file_path = find_wiki_file(name)
     with open(file_path, 'r') as csvfile:
+        csvfile = filter(lambda row: row[0] !='#', csvfile) # strip "#..."
         reader = csv.DictReader(csvfile)
         return list(reader)
 
@@ -60,6 +68,26 @@ def get_signal_name(name):
         name = "is_" + name
     return name.lower().replace(' ', '_')
 
+
+class Enum(_Enum):
+    @classmethod
+    def _missing_(cls, value):
+        if isinstance(value, str):
+            try:
+                if value == "":
+                    value = 0
+                else:
+                    value = int(value, 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
+
+
 # this corresponds to which Function Unit (pipeline-with-Reservation-Stations)
 # is to process and guard the operation.  they are roughly divided by having
 # the same register input/output signature (X-Form, etc.)
@@ -83,6 +111,20 @@ class Function(Enum):
     VL = 1 << 13  # setvl
     FPU = 1 << 14  # FPU
 
+    @functools.lru_cache(maxsize=None)
+    def __repr__(self):
+        counter = 0
+        value = int(self.value)
+        if value != 0:
+            while value != 0:
+                counter += 1
+                value >>= 1
+            counter -= 1
+            desc = f"(1 << {counter})"
+        else:
+            desc = "0"
+        return f"<{self.__class__.__name__}.{self.name}: {desc}>"
+
 
 @unique
 class Form(Enum):
@@ -118,19 +160,45 @@ 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 - TEMPORARY TEMPORARY TEMPORARY
-    TI = 34  # ternaryi
+    SVM = 32  # Simple-V SHAPE mode
+    SVM2 = 33  # Simple-V SHAPE2 mode - fits into SVM
+    SVRM = 34  # Simple-V REMAP mode
+    TLI = 35  # ternlogi
+    XB = 36
+    BM2 = 37 # bmask
+    SVI = 38  # Simple-V Index Mode
+    VA2 = 39
+    SVC = 40
+    SVR = 41
 
 # Simple-V svp64 fields https://libre-soc.org/openpower/sv/svp64/
 
 
+class SVMode(Enum):
+    NORMAL = auto()
+    LDST_IDX = auto()
+    LDST_IMM = auto()
+    BRANCH = auto()
+    CROP = auto()
+
+
 @unique
 class SVPtype(Enum):
     NONE = 0
     P1 = 1
     P2 = 2
 
+    @classmethod
+    def _missing_(cls, value):
+        return {"1P": SVPtype.P1, "2P": SVPtype.P2}[value]
+
+    def __repr__(self):
+        return {
+            SVPtype.NONE: "NONE",
+            SVPtype.P1: "1P",
+            SVPtype.P2: "2P",
+        }[self]
+
 
 @unique
 class SVEtype(Enum):
@@ -138,9 +206,21 @@ class SVEtype(Enum):
     EXTRA2 = 1
     EXTRA3 = 2
 
+    def __repr__(self):
+        return self.name
+
 
 @unique
-class SVEXTRA(Enum):
+class SVmask_src(Enum):
+    NO = 0
+    EN = 1
+
+    def __repr__(self):
+        return self.name
+
+
+@unique
+class SVExtra(Enum):
     NONE = 0
     Idx0 = 1
     Idx1 = 2
@@ -148,6 +228,64 @@ class SVEXTRA(Enum):
     Idx3 = 4
     Idx_1_2 = 5  # due to weird BA/BB for crops
 
+    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]",
+        }[self]
+
+# Backward compatibility
+SVEXTRA = SVExtra
+
+
+class SVExtraRegType(Enum):
+    NONE = None
+    SRC = 's'
+    DST = 'd'
+
+
+class SVExtraReg(Enum):
+    NONE = auto()
+    RA = auto()
+    RA_OR_ZERO = RA
+    RB = auto()
+    RC = auto()
+    RS = auto()
+    RT = auto()
+    RT_OR_ZERO = RT
+    FRA = auto()
+    FRB = auto()
+    FRC = auto()
+    FRS = auto()
+    FRT = auto()
+    CR = auto()
+    CR0 = auto()
+    CR1 = auto()
+    BF = auto()
+    BFA = auto()
+    BA = auto()
+    BB = auto()
+    BC = auto()
+    BI = auto()
+    BT = auto()
+    BFT = auto()
+    WHOLE_REG = auto()
+    SPR = auto()
+
+    @classmethod
+    def _missing_(cls, value):
+        selectors = (
+            In1Sel, In2Sel, In3Sel, CRInSel, CRIn2Sel,
+            OutSel, CROutSel,
+        )
+        if isinstance(value, selectors):
+            return cls.__members__[value.name]
+        return super()._missing_(value)
+
 
 @unique
 class SVP64PredMode(Enum):
@@ -247,7 +385,101 @@ class SVP64LDSTmode(Enum):
     INDEXED = 1
     ELSTRIDE = 2
     UNITSTRIDE = 3
-    SHIFT = 4
+
+
+class RegType(Enum):
+    GPR = 0
+    RA = GPR
+    RB = GPR
+    RC = GPR
+    RS = GPR
+    RT = GPR
+
+    FPR = 1
+    FRA = FPR
+    FRB = FPR
+    FRC = FPR
+    FRS = FPR
+    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
+
+    @classmethod
+    def _missing_(cls, value):
+        if isinstance(value, SVExtraReg):
+            return cls.__members__[value.name]
+        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",
+    "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
@@ -259,20 +491,28 @@ _insns = [
     "addg6s",
     "and", "andc", "andi.", "andis.",
     "attn",
+    "absdu", "absds",                         # AV bitmanip
+    "absdacs", "absdacu",                     # AV bitmanip
+    "avgadd",                                 # AV bitmanip
     "b", "bc", "bcctr", "bclr", "bctar",
+    "bmask",                                  # AV bitmanip
     "bpermd",
     "cbcdtd",
     "cdtbcd",
     "cmp", "cmpb", "cmpeqb", "cmpi", "cmpl", "cmpli", "cmprb",
     "cntlzd", "cntlzw", "cnttzd", "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",
-    "eqv",
+    "dsld", "dsrd",
+    "eieio", "eqv",
     "extsb", "extsh", "extsw", "extswsli",
     "fadd", "fadds", "fsub", "fsubs",                   # FP add / sub
     "fcfids", "fcfidus", "fsqrts", "fres", "frsqrtes",  # FP stuff
@@ -282,9 +522,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.',
     "hrfid", "icbi", "icbt", "isel", "isync",
-    "lbarx", "lbz", "lbzu", "lbzux", "lbzx",            # load byte
+    "lbarx", "lbz", "lbzcix", "lbzu", "lbzux", "lbzx",  # load byte
     "ld", "ldarx", "ldbrx", "ldu", "ldux", "ldx",       # load double
     # "lbzbr", "lbzubr",  # load byte SVP64 bit-reversed
     # "ldbr", "ldubr",    # load double SVP64 bit-reversed
@@ -298,9 +541,11 @@ _insns = [
     "lwz", "lwzcix", "lwzu", "lwzux", "lwzx",           # more load word
     # "lwabr",           # load word SVP64 bit-reversed
     # "lwzbr", "lwzubr", # more load word SVP64 bit-reversed
+    "maddedu",
     "maddhd", "maddhdu", "maddld",                      # INT multiply-and-add
     "mcrf", "mcrxr", "mcrxrx", "mfcr/mfocrf",           # CR mvs
     "mfmsr", "mfspr",
+    "mins", "maxs", "minu", "maxu",                     # AV bitmanip
     "modsd", "modsw", "modud", "moduw",
     "mtcrf/mtocrf", "mtmsr", "mtmsrd", "mtspr",
     "mulhd", "mulhdu", "mulhw", "mulhwu", "mulld", "mulldo",
@@ -308,6 +553,7 @@ _insns = [
     "nand", "neg", "nego",
     "nop",
     "nor", "or", "orc", "ori", "oris",
+    "pcdec",
     "popcntb", "popcntd", "popcntw",
     "prtyd", "prtyw",
     "rfid",
@@ -315,8 +561,10 @@ _insns = [
     "rlwimi", "rlwinm",    "rlwnm",
     "setb",
     "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",
     "slbia", "sld", "slw", "srad", "sradi",
@@ -330,11 +578,13 @@ _insns = [
     "subf", "subfc", "subfco", "subfe", "subfeo", "subfic",
     "subfme", "subfmeo", "subfo", "subfze", "subfzeo",
     "sync",
-    "ternaryi",
+    "ternlogi",
     "td", "tdi",
-    "tlbie", "tlbiel",
+    "tlbie", "tlbiel", "tlbsync",
     "tw", "twi",
+    "wait",
     "xor", "xori", "xoris",
+    *FPTRANS_INSNS,
 ]
 
 # two-way lookup of instruction-to-index and vice-versa
@@ -435,7 +685,23 @@ class MicrOp(Enum):
     OP_ADDG6S = 83
     OP_CDTBCD = 84
     OP_CBCDTD = 85
-    OP_TERNARY = 86
+    OP_TERNLOG = 86
+    OP_FETCH_FAILED = 87
+    OP_GREV = 88
+    OP_MINMAX = 89
+    OP_AVGADD = 90
+    OP_ABSDIFF = 91
+    OP_ABSADD = 92
+    OP_CPROP = 93
+    OP_BMASK = 94
+    OP_SVINDEX = 95
+    OP_FMVIS = 96
+    OP_FISHMV = 97
+    OP_PCDEC = 98
+    OP_MADDEDU = 99
+    OP_DIVMOD2DU = 100
+    OP_DSHL = 101
+    OP_DSHR = 102
 
 
 @unique
@@ -447,6 +713,7 @@ class In1Sel(Enum):
     RS = 4  # for some ALU/Logical operations
     FRA = 5
     FRS = 6
+    CIA = 7 # for addpcis
 
 
 @unique
@@ -468,6 +735,8 @@ class In2Sel(Enum):
     FRB = 14
     CONST_SVD = 15  # for SVD-Form
     CONST_SVDS = 16  # for SVDS-Form
+    CONST_XBI = 17
+    CONST_DXHI4 = 18 # for addpcis
 
 
 @unique
@@ -478,7 +747,7 @@ class In3Sel(Enum):
     FRS = 3
     FRC = 4
     RC = 5  # for SVP64 bit-reverse LD/ST
-    RT = 6  # for ternary[i]
+    RT = 6  # for ternlog[i]
 
 
 @unique
@@ -490,16 +759,20 @@ class OutSel(Enum):
     RT_OR_ZERO = 4
     FRT = 5
     FRS = 6
+    RS = 7
 
 
 @unique
-class LdstLen(Enum):
+class LDSTLen(Enum):
     NONE = 0
     is1B = 1
     is2B = 2
     is4B = 4
     is8B = 8
 
+# Backward compatibility
+LdstLen = LDSTLen
+
 
 @unique
 class LDSTMode(Enum):
@@ -510,10 +783,11 @@ class LDSTMode(Enum):
 
 
 @unique
-class RC(Enum):
+class RCOE(Enum):
     NONE = 0
     ONE = 1
-    RC = 2
+    RC = 2    # includes OE
+    RC_ONLY = 3  # does not include OE
 
 
 @unique
@@ -534,6 +808,13 @@ class CRInSel(Enum):
     BC = 5
     WHOLE_REG = 6
     CR1 = 7
+    BA = 8
+
+
+@unique
+class CRIn2Sel(Enum):
+    NONE = 0
+    BB = 1
 
 
 @unique
@@ -549,6 +830,7 @@ class CROutSel(Enum):
 # SPRs - Special-Purpose Registers.  See V3.0B Figure 18 p971 and
 # http://libre-riscv.org/openpower/isatables/sprs.csv
 # http://bugs.libre-riscv.org/show_bug.cgi?id=261
+# http://bugs.libre-riscv.org/show_bug.cgi?id=859 - KAIVB
 
 def get_spr_enum(full_file):
     """get_spr_enum - creates an Enum of SPRs, dynamically
@@ -558,7 +840,10 @@ def get_spr_enum(full_file):
     short_list = {'PIDR', 'DAR', 'PRTBL', 'DSISR', 'SVSRR0', 'SVSTATE',
                   'SVSTATE0', 'SVSTATE1', 'SVSTATE2', 'SVSTATE3',
                   'SPRG0_priv', 'SPRG1_priv', 'SPRG2_priv', 'SPRG3_priv',
-                  'SPRG3'
+                  'SPRG0', 'SPRG1', 'SPRG2', 'SPRG3', 'KAIVB',
+                  # hmmm should not be including these, they are FAST regs
+                  'CTR', 'LR', 'TAR', 'SRR0', 'SRR1', 'XER', 'DEC', 'TB', 'TBU',
+                  'HSRR0', 'HSRR1', 'HSPRG0', 'HSPRG1',
                   }
     spr_csv = []
     for row in get_csv("sprs.csv"):
@@ -590,6 +875,8 @@ XER_bits = {
     'CA32': 45
 }
 
+MSRSpec = namedtuple("MSRSpec", ["dr", "pr", "sf"])
+
 if __name__ == '__main__':
     # find out what the heck is in SPR enum :)
     print("sprs full", len(SPRfull))