start adding svp64 enums
[soc.git] / src / soc / decoder / power_enums.py
index 05e23f8e8ee1f0bddc412c48f1cc08bf6fe6b6de..74c149e3b5cc5e45d8212b879ebb8ce74128be2e 100644 (file)
@@ -1,9 +1,21 @@
+# SPDX-License: LGPLv3+
+# Copyright (C) 2020, 2021 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
+# Copyright (C) 2020, Michael Nolan
+
 from enum import Enum, unique
 import csv
 import os
 from os.path import dirname, join
 from collections import namedtuple
 
+
+def find_wiki_dir():
+    filedir = os.path.dirname(os.path.abspath(__file__))
+    basedir = dirname(dirname(dirname(filedir)))
+    tabledir = join(basedir, 'libreriscv')
+    tabledir = join(tabledir, 'openpower')
+    return join(tabledir, 'isatables')
+
 def find_wiki_file(name):
     filedir = os.path.dirname(os.path.abspath(__file__))
     basedir = dirname(dirname(dirname(filedir)))
@@ -11,8 +23,7 @@ def find_wiki_file(name):
     tabledir = join(tabledir, 'openpower')
     tabledir = join(tabledir, 'isatables')
 
-    file_path = join(tabledir, name)
-    return file_path
+    return join(find_wiki_dir(), name)
 
 
 def get_csv(name):
@@ -24,7 +35,7 @@ def get_csv(name):
 
 # names of the fields in the tables that don't correspond to an enum
 single_bit_flags = ['inv A', 'inv out',
-                    'cry out', 'BR', 'sgn ext', 'upd', 'rsrv', '32b',
+                    'cry out', 'BR', 'sgn ext', 'rsrv', '32b',
                     'sgn', 'lk', 'sgl pipe']
 
 # default values for fields in the table
@@ -32,6 +43,7 @@ default_values = {'unit': "NONE", 'internal op': "OP_ILLEGAL",
                   'in1': "RA", 'in2': 'NONE', 'in3': 'NONE', 'out': 'NONE',
                   'CR in': 'NONE',
                   'ldst len': 'NONE',
+                  'upd': '0',
                   'rc': 'NONE', 'cry in': 'ZERO', 'form': 'NONE'}
 
 
@@ -46,15 +58,18 @@ def get_signal_name(name):
 @unique
 class Function(Enum):
     NONE = 0
-    ALU = 1
-    LDST = 2
-    SHIFT_ROT = 3
-    LOGICAL = 4
-    BRANCH = 5
-    CR = 6
-    TRAP = 7
-    MUL = 8
-    DIV = 9
+    ALU = 1 << 1
+    LDST = 1 << 2
+    SHIFT_ROT = 1 << 3
+    LOGICAL = 1 << 4
+    BRANCH = 1 << 5
+    CR = 1 << 6
+    TRAP = 1 << 7
+    MUL = 1 << 8
+    DIV = 1 << 9
+    SPR = 1 << 10
+    MMU = 1 << 11
+    SV = 1 << 12 # Simple-V https://libre-soc.org/openpower/sv
 
 
 @unique
@@ -89,10 +104,64 @@ class Form(Enum):
     Z22 = 27
     Z23 = 28
 
+# Simple-V svp64 fields https://libre-soc.org/openpower/sv/svp64/
+
+@unique
+class SVPtype(Enum):
+    NONE = 0
+    P1 = 1
+    P2 = 2
+
+@unique
+class SVEtype(Enum):
+    NONE = 0
+    EXTRA2 = 1
+    EXTRA3 = 2
+
+# supported instructions: make sure to keep up-to-date with CSV files
+# just like everything else
+_insns = [
+    "NONE", "add", "addc", "addco", "adde", "addeo", "addi", "addic", "addic.",
+    "addis", "addme", "addmeo", "addo", "addze", "addzeo", "and", "andc",
+    "andi.", "andis.", "attn", "b", "bc", "bcctr", "bclr", "bctar",
+    "bpermd", "cmp", "cmpb", "cmpeqb", "cmpi", "cmpl", "cmpli", "cmprb",
+    "cntlzd", "cntlzw", "cnttzd", "cnttzw", "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",
+    "divweu", "divweuo", "divwo", "divwu", "divwuo", "eqv", "extsb",
+    "extsh", "extsw", "extswsli", "hrfid", "icbi", "icbt", "isel", "isync",
+    "lbarx", "lbz", "lbzu", "lbzux", "lbzx", "ld", "ldarx", "ldbrx",
+    "ldu", "ldux", "ldx", "lha", "lharx", "lhau", "lhaux", "lhax",
+    "lhbrx", "lhz", "lhzu", "lhzux", "lhzx", "lwa", "lwarx", "lwaux",
+    "lwax", "lwbrx", "lwz", "lwzcix", "lwzu", "lwzux", "lwzx", "mcrf", "mcrxr",
+    "mcrxrx", "mfcr/mfocrf", "mfmsr", "mfspr", "modsd", "modsw", "modud",
+    "moduw", "mtcrf/mtocrf", "mtmsr", "mtmsrd", "mtspr", "mulhd", "mulhdu",
+    "mulhw", "mulhwu", "mulld", "mulldo", "mulli", "mullw", "mullwo",
+    "nand", "neg", "nego", "nop", "nor", "or", "orc", "ori", "oris",
+    "popcntb", "popcntd", "popcntw", "prtyd", "prtyw", "rfid", "rldcl",
+    "rldcr", "rldic", "rldicl", "rldicr", "rldimi", "rlwimi", "rlwinm",
+    "rlwnm", "setb",
+    "setvl", # https://libre-soc.org/openpower/sv/setvl
+    "sim_cfg", "slbia", "sld", "slw", "srad", "sradi", "sraw",
+    "srawi", "srd", "srw", "stb", "stbcix", "stbcx", "stbu", "stbux", "stbx",
+    "std", "stdbrx", "stdcx", "stdu", "stdux", "stdx", "sth", "sthbrx", "sthcx",
+    "sthu", "sthux", "sthx", "stw", "stwbrx", "stwcx", "stwu", "stwux",
+    "stwx", "subf", "subfc", "subfco", "subfe", "subfeo", "subfic",
+    "subfme", "subfmeo", "subfo", "subfze", "subfzeo", "sync", "td",
+    "tdi", "tlbie", "tlbiel", "tw", "twi", "xor", "xori", "xoris",
+]
+
+# two-way lookup of instruction-to-index and vice-versa
+insns = {}
+asmidx = {}
+for i, insn in enumerate(_insns):
+    insns[i] = insn
+    asmidx[insn] = i
 
 # Internal Operation numbering.  Add new opcodes here (FPADD, FPMUL etc.)
 @unique
-class InternalOp(Enum):
+class MicrOp(Enum):
     OP_ILLEGAL = 0     # important that this is zero (see power_decoder.py)
     OP_NOP = 1
     OP_ADD = 2
@@ -163,6 +232,9 @@ class InternalOp(Enum):
     OP_RFID = 70
     OP_MFMSR = 71
     OP_MTMSRD = 72
+    OP_SC = 73
+    OP_MTMSR = 74
+    OP_TLBIE = 75
 
 
 @unique
@@ -171,6 +243,7 @@ class In1Sel(Enum):
     RA = 1
     RA_OR_ZERO = 2
     SPR = 3
+    RS = 4  # for some ALU/Logical operations
 
 
 @unique
@@ -188,12 +261,14 @@ class In2Sel(Enum):
     CONST_SH = 10
     CONST_SH32 = 11
     SPR = 12
+    RS = 13  # for shiftrot (M-Form)
 
 
 @unique
 class In3Sel(Enum):
     NONE = 0
     RS = 1
+    RB = 2  # for shiftrot (M-Form)
 
 
 @unique
@@ -209,8 +284,16 @@ class LdstLen(Enum):
     NONE = 0
     is1B = 1
     is2B = 2
-    is4B = 3
-    is8B = 4
+    is4B = 4
+    is8B = 8
+
+
+@unique
+class LDSTMode(Enum):
+    NONE = 0
+    update = 1
+    cix = 2
+    cx = 3
 
 
 @unique
@@ -225,6 +308,8 @@ class CryIn(Enum):
     ZERO = 0
     ONE = 1
     CA = 2
+    # TODO OV = 3
+
 
 @unique
 class CRInSel(Enum):
@@ -235,6 +320,8 @@ class CRInSel(Enum):
     BA_BB = 4
     BC = 5
     WHOLE_REG = 6
+    CR1 = 7
+
 
 @unique
 class CROutSel(Enum):
@@ -243,6 +330,7 @@ class CROutSel(Enum):
     BF = 2
     BT = 3
     WHOLE_REG = 4
+    CR1 = 5
 
 
 # SPRs - Special-Purpose Registers.  See V3.0B Figure 18 p971 and
@@ -250,12 +338,15 @@ class CROutSel(Enum):
 # http://bugs.libre-riscv.org/show_bug.cgi?id=261
 
 spr_csv = get_csv("sprs.csv")
-spr_info = namedtuple('spr_info', 'SPR priv_mtspr priv_mfspr length')
+spr_info = namedtuple('spr_info', 'SPR priv_mtspr priv_mfspr length idx')
 spr_dict = {}
+spr_byname = {}
 for row in spr_csv:
     info = spr_info(SPR=row['SPR'], priv_mtspr=row['priv_mtspr'],
-                    priv_mfspr=row['priv_mfspr'], length=int(row['len']))
+                    priv_mfspr=row['priv_mfspr'], length=int(row['len']),
+                    idx=int(row['Idx']))
     spr_dict[int(row['Idx'])] = info
+    spr_byname[row['SPR']] = info
 fields = [(row['SPR'], int(row['Idx'])) for row in spr_csv]
 SPR = Enum('SPR', fields)
 
@@ -266,12 +357,15 @@ XER_bits = {
     'CA': 34,
     'OV32': 44,
     'CA32': 45
-    }
+}
 
 if __name__ == '__main__':
     # find out what the heck is in SPR enum :)
-    print ("sprs", len(SPR))
-    print (dir(SPR))
-    print (dir(Enum))
+    print("sprs", len(SPR))
+    print(dir(SPR))
+    print(dir(Enum))
+    print(SPR.__members__['TAR'])
     for x in SPR:
-        print (x, x.value)
+        print(x, x.value, str(x), x.name)
+
+    print ("function", Function.ALU.name)