X-Git-Url: https://git.libre-soc.org/?p=soc.git;a=blobdiff_plain;f=src%2Fsoc%2Fdecoder%2Fpower_enums.py;h=74c149e3b5cc5e45d8212b879ebb8ce74128be2e;hp=ab838132b30100fe832adfaecabf0d6bbbfa7787;hb=23017a47970e7908664056261c3e2836a0257e44;hpb=7f04d9931f6a33e2e4a879d3284b273a6406b6d0 diff --git a/src/soc/decoder/power_enums.py b/src/soc/decoder/power_enums.py index ab838132..74c149e3 100644 --- a/src/soc/decoder/power_enums.py +++ b/src/soc/decoder/power_enums.py @@ -1,49 +1,75 @@ +# SPDX-License: LGPLv3+ +# Copyright (C) 2020, 2021 Luke Kenneth Casson Leighton +# Copyright (C) 2020, Michael Nolan + from enum import Enum, unique import csv import os -import requests +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 download_wiki_file(name): - file_dir = os.path.dirname(os.path.realpath(__file__)) - file_path = os.path.join(file_dir, name) - if not os.path.isfile(file_path): - url = 'https://libre-riscv.org/openpower/isatables/' + name - r = requests.get(url, allow_redirects=True) - with open(file_path, 'w') as outfile: - outfile.write(r.content.decode("utf-8")) - return file_path +def find_wiki_file(name): + filedir = os.path.dirname(os.path.abspath(__file__)) + basedir = dirname(dirname(dirname(filedir))) + tabledir = join(basedir, 'libreriscv') + tabledir = join(tabledir, 'openpower') + tabledir = join(tabledir, 'isatables') + + return join(find_wiki_dir(), name) def get_csv(name): - file_path = download_wiki_file(name) + file_path = find_wiki_file(name) with open(file_path, 'r') as csvfile: reader = csv.DictReader(csvfile) return list(reader) # names of the fields in the tables that don't correspond to an enum -single_bit_flags = ['CR in', 'CR out', 'inv A', 'inv out', - 'cry out', 'BR', 'sgn ext', 'upd', 'rsrv', '32b', +single_bit_flags = ['inv A', 'inv out', + 'cry out', 'BR', 'sgn ext', 'rsrv', '32b', 'sgn', 'lk', 'sgl pipe'] # default values for fields in the table default_values = {'unit': "NONE", 'internal op': "OP_ILLEGAL", - 'in1': "RA", 'in2': 'NONE', 'in3': 'NONE', 'out': 'NONE', - 'ldst len': 'NONE', - 'rc' : 'NONE', 'cry in' : 'ZERO', 'form': 'NONE'} + 'in1': "RA", 'in2': 'NONE', 'in3': 'NONE', 'out': 'NONE', + 'CR in': 'NONE', + 'ldst len': 'NONE', + 'upd': '0', + 'rc': 'NONE', 'cry in': 'ZERO', 'form': 'NONE'} + def get_signal_name(name): if name[0].isdigit(): name = "is_" + name return name.lower().replace(' ', '_') - +# 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.) @unique class Function(Enum): NONE = 0 - ALU = 1 - LDST = 2 + 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 @@ -78,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 @@ -145,12 +225,16 @@ class InternalOp(Enum): OP_SHL = 60 OP_SHR = 61 OP_SYNC = 62 - OP_TD = 63 - OP_TDI = 64 - OP_TW = 65 - OP_TWI = 66 + OP_TRAP = 63 OP_XOR = 67 OP_SIM_CONFIG = 68 + OP_CROP = 69 + OP_RFID = 70 + OP_MFMSR = 71 + OP_MTMSRD = 72 + OP_SC = 73 + OP_MTMSR = 74 + OP_TLBIE = 75 @unique @@ -159,6 +243,7 @@ class In1Sel(Enum): RA = 1 RA_OR_ZERO = 2 SPR = 3 + RS = 4 # for some ALU/Logical operations @unique @@ -176,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 @@ -197,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 @@ -213,6 +308,29 @@ class CryIn(Enum): ZERO = 0 ONE = 1 CA = 2 + # TODO OV = 3 + + +@unique +class CRInSel(Enum): + NONE = 0 + CR0 = 1 + BI = 2 + BFA = 3 + BA_BB = 4 + BC = 5 + WHOLE_REG = 6 + CR1 = 7 + + +@unique +class CROutSel(Enum): + NONE = 0 + CR0 = 1 + BF = 2 + BT = 3 + WHOLE_REG = 4 + CR1 = 5 # SPRs - Special-Purpose Registers. See V3.0B Figure 18 p971 and @@ -220,5 +338,34 @@ class CryIn(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 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']), + 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) + + +XER_bits = { + 'SO': 32, + 'OV': 33, + '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(SPR.__members__['TAR']) + for x in SPR: + print(x, x.value, str(x), x.name) + + print ("function", Function.ALU.name)