0788642b0c338db1e1b0ba11bfe4b9bbcbf49434
1 # SPDX-License: LGPLv3+
2 # Copyright (C) 2020, 2021 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
3 # Copyright (C) 2020, Michael Nolan
5 """Enums used in OpenPOWER ISA decoding
7 Note: for SV, from v3.1B p12:
9 The designated SPR sandbox consists of non-privileged SPRs 704-719 and
10 privileged SPRs 720-735.
12 Note: the option exists to select a much shorter list of SPRs, to reduce
13 regfile size in HDL. this is SPRreduced and the supported list is in
17 from enum
import Enum
, unique
20 from os
.path
import dirname
, join
21 from collections
import namedtuple
25 filedir
= os
.path
.dirname(os
.path
.abspath(__file__
))
26 basedir
= dirname(dirname(dirname(filedir
)))
27 tabledir
= join(basedir
, 'openpower')
28 isatables
= join(tabledir
, 'isatables')
29 #print ("find_wiki_dir", isatables)
33 def find_wiki_file(name
):
34 return join(find_wiki_dir(), name
)
38 file_path
= find_wiki_file(name
)
39 with
open(file_path
, 'r') as csvfile
:
40 reader
= csv
.DictReader(csvfile
)
44 # names of the fields in the tables that don't correspond to an enum
45 single_bit_flags
= ['inv A', 'inv out',
46 'cry out', 'BR', 'sgn ext', 'rsrv', '32b',
47 'sgn', 'lk', 'sgl pipe']
49 # default values for fields in the table
50 default_values
= {'unit': "NONE", 'internal op': "OP_ILLEGAL",
51 'in1': "RA", 'in2': 'NONE', 'in3': 'NONE', 'out': 'NONE',
55 'rc': 'NONE', 'cry in': 'ZERO', 'form': 'NONE'}
58 def get_signal_name(name
):
61 return name
.lower().replace(' ', '_')
63 # this corresponds to which Function Unit (pipeline-with-Reservation-Stations)
64 # is to process and guard the operation. they are roughly divided by having
65 # the same register input/output signature (X-Form, etc.)
82 SV
= 1 << 12 # Simple-V https://libre-soc.org/openpower/sv
118 SVL
= 29 # Simple-V for setvl instruction
120 # Simple-V svp64 fields https://libre-soc.org/openpower/sv/svp64/
144 Idx_1_2
= 5 # due to weird BA/BB for crops
148 class SVP64PredMode(Enum
):
155 class SVP64PredInt(Enum
):
167 class SVP64PredCR(Enum
):
179 class SVP64RMMode(Enum
):
188 class SVP64width(Enum
):
196 class SVP64subvl(Enum
):
204 class SVP64sat(Enum
):
210 class SVP64LDSTmode(Enum
):
218 # supported instructions: make sure to keep up-to-date with CSV files
219 # just like everything else
221 "NONE", "add", "addc", "addco", "adde", "addeo",
222 "addi", "addic", "addic.", "addis",
223 "addme", "addmeo", "addo", "addze", "addzeo",
224 "and", "andc", "andi.", "andis.",
226 "b", "bc", "bcctr", "bclr", "bctar",
228 "cmp", "cmpb", "cmpeqb", "cmpi", "cmpl", "cmpli", "cmprb",
229 "cntlzd", "cntlzw", "cnttzd", "cnttzw",
230 "crand", "crandc", "creqv",
231 "crnand", "crnor", "cror", "crorc", "crxor",
233 "dcbf", "dcbst", "dcbt", "dcbtst", "dcbz",
234 "divd", "divde", "divdeo", "divdeu",
235 "divdeuo", "divdo", "divdu", "divduo", "divw", "divwe", "divweo",
236 "divweu", "divweuo", "divwo", "divwu", "divwuo",
238 "extsb", "extsh", "extsw", "extswsli",
239 "fadd", "fadds", "fsub", "fsubs", # FP add / sub
240 "fcfids", "fcfidus", "fsqrts", "fres", "frsqrtes", # FP stuff
241 "fmsubs", "fmadds", "fnmsubs", "fnmadds", # FP 3-arg
242 "fmul", "fmuls", "fdiv", "fdivs", # FP mul / div
243 "fmr", "fabs", "fnabs", "fneg", "fcpsgn", # FP move/abs/neg
244 "hrfid", "icbi", "icbt", "isel", "isync",
245 "lbarx", "lbz", "lbzu", "lbzux", "lbzx", # load byte
246 "ld", "ldarx", "ldbrx", "ldu", "ldux", "ldx", # load double
247 "lfs", "lfsx", "lfsu", "lfsux", # FP load single
248 "lfd", "lfdx", "lfdu", "lfdux", "lfiwzx", "lfiwax", # FP load double
249 "lha", "lharx", "lhau", "lhaux", "lhax", # load half
250 "lhbrx", "lhz", "lhzu", "lhzux", "lhzx", # more load half
251 "lwa", "lwarx", "lwaux", "lwax", "lwbrx", # load word
252 "lwz", "lwzcix", "lwzu", "lwzux", "lwzx", # more load word
253 "maddhd", "maddhdu", "maddld", # INT multiply-and-add
254 "mcrf", "mcrxr", "mcrxrx", "mfcr/mfocrf", # CR mvs
256 "modsd", "modsw", "modud", "moduw",
257 "mtcrf/mtocrf", "mtmsr", "mtmsrd", "mtspr",
258 "mulhd", "mulhdu", "mulhw", "mulhwu", "mulld", "mulldo",
259 "mulli", "mullw", "mullwo",
260 "nand", "neg", "nego",
262 "nor", "or", "orc", "ori", "oris",
263 "popcntb", "popcntd", "popcntw",
266 "rldcl", "rldcr", "rldic", "rldicl", "rldicr", "rldimi",
267 "rlwimi", "rlwinm", "rlwnm",
269 "setvl", # https://libre-soc.org/openpower/sv/setvl
271 "slbia", "sld", "slw", "srad", "sradi",
272 "sraw", "srawi", "srd", "srw",
273 "stb", "stbcix", "stbcx", "stbu", "stbux", "stbx",
274 "std", "stdbrx", "stdcx", "stdu", "stdux", "stdx",
275 "stfs", "stfsx", "stfsu", "stfux", # FP store single
276 "stfd", "stfdx", "stfdu", "stfdux", "stfiwx", # FP store double
277 "sth", "sthbrx", "sthcx", "sthu", "sthux", "sthx",
278 "stw", "stwbrx", "stwcx", "stwu", "stwux", "stwx",
279 "subf", "subfc", "subfco", "subfe", "subfeo", "subfic",
280 "subfme", "subfmeo", "subfo", "subfze", "subfzeo",
285 "xor", "xori", "xoris",
288 # two-way lookup of instruction-to-index and vice-versa
291 for i
, insn
in enumerate(_insns
):
295 # Internal Operation numbering. Add new opcodes here (FPADD, FPMUL etc.)
300 OP_ILLEGAL
= 0 # important that this is zero (see power_decoder.py)
374 OP_FPOP
= 77 # temporary: replace with actual ops
375 OP_FPOP_I
= 78 # temporary: replace with actual ops
384 RS
= 4 # for some ALU/Logical operations
404 RS
= 13 # for shiftrot (M-Form)
412 RB
= 2 # for shiftrot (M-Form)
437 class LDSTMode(Enum
):
472 class CROutSel(Enum
):
481 # SPRs - Special-Purpose Registers. See V3.0B Figure 18 p971 and
482 # http://libre-riscv.org/openpower/isatables/sprs.csv
483 # http://bugs.libre-riscv.org/show_bug.cgi?id=261
485 def get_spr_enum(full_file
):
486 """get_spr_enum - creates an Enum of SPRs, dynamically
487 has the option to reduce the enum to a much shorter list.
488 this saves drastically on the size of the regfile
490 short_list
= {'PIDR', 'DAR', 'PRTBL', 'DSISR', 'SVSRR0', 'SVSTATE',
491 'SPRG0_priv', 'SPRG1_priv', 'SPRG2_priv', 'SPRG3_priv',
495 for row
in get_csv("sprs.csv"):
496 if full_file
or row
['SPR'] in short_list
:
499 spr_info
= namedtuple('spr_info', 'SPR priv_mtspr priv_mfspr length idx')
503 info
= spr_info(SPR
=row
['SPR'], priv_mtspr
=row
['priv_mtspr'],
504 priv_mfspr
=row
['priv_mfspr'], length
=int(row
['len']),
506 spr_dict
[int(row
['Idx'])] = info
507 spr_byname
[row
['SPR']] = info
508 fields
= [(row
['SPR'], int(row
['Idx'])) for row
in spr_csv
]
509 SPR
= Enum('SPR', fields
)
510 return SPR
, spr_dict
, spr_byname
512 SPRfull
, spr_dict
, spr_byname
= get_spr_enum(full_file
=True)
513 SPRreduced
, _
, _
= get_spr_enum(full_file
=False)
523 if __name__
== '__main__':
524 # find out what the heck is in SPR enum :)
525 print("sprs full", len(SPRfull
))
527 print("sprs reduced", len(SPRreduced
))
528 print(dir(SPRreduced
))
530 print(SPRfull
.__members
__['TAR'])
532 print("full", x
, x
.value
, str(x
), x
.name
)
534 print("reduced", x
, x
.value
, str(x
), x
.name
)
536 print("function", Function
.ALU
.name
)