3353d202526ee2a885fd645282ab5b94c7320ef5
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
, 'libreriscv')
28 tabledir
= join(tabledir
, 'openpower')
29 return join(tabledir
, 'isatables')
32 def find_wiki_file(name
):
33 filedir
= os
.path
.dirname(os
.path
.abspath(__file__
))
34 basedir
= dirname(dirname(dirname(filedir
)))
35 tabledir
= join(basedir
, 'libreriscv')
36 tabledir
= join(tabledir
, 'openpower')
37 tabledir
= join(tabledir
, 'isatables')
39 return join(find_wiki_dir(), name
)
43 file_path
= find_wiki_file(name
)
44 with
open(file_path
, 'r') as csvfile
:
45 reader
= csv
.DictReader(csvfile
)
49 # names of the fields in the tables that don't correspond to an enum
50 single_bit_flags
= ['inv A', 'inv out',
51 'cry out', 'BR', 'sgn ext', 'rsrv', '32b',
52 'sgn', 'lk', 'sgl pipe']
54 # default values for fields in the table
55 default_values
= {'unit': "NONE", 'internal op': "OP_ILLEGAL",
56 'in1': "RA", 'in2': 'NONE', 'in3': 'NONE', 'out': 'NONE',
60 'rc': 'NONE', 'cry in': 'ZERO', 'form': 'NONE'}
63 def get_signal_name(name
):
66 return name
.lower().replace(' ', '_')
68 # this corresponds to which Function Unit (pipeline-with-Reservation-Stations)
69 # is to process and guard the operation. they are roughly divided by having
70 # the same register input/output signature (X-Form, etc.)
87 SV
= 1 << 12 # Simple-V https://libre-soc.org/openpower/sv
122 SVL
= 29 # Simple-V for setvl instruction
124 # Simple-V svp64 fields https://libre-soc.org/openpower/sv/svp64/
148 Idx_1_2
= 5 # due to weird BA/BB for crops
152 class SVP64PredMode(Enum
):
159 class SVP64PredInt(Enum
):
171 class SVP64PredCR(Enum
):
183 class SVP64RMMode(Enum
):
192 class SVP64width(Enum
):
200 class SVP64subvl(Enum
):
208 class SVP64sat(Enum
):
214 # supported instructions: make sure to keep up-to-date with CSV files
215 # just like everything else
217 "NONE", "add", "addc", "addco", "adde", "addeo", "addi", "addic", "addic.",
218 "addis", "addme", "addmeo", "addo", "addze", "addzeo", "and", "andc",
219 "andi.", "andis.", "attn", "b", "bc", "bcctr", "bclr", "bctar",
220 "bpermd", "cmp", "cmpb", "cmpeqb", "cmpi", "cmpl", "cmpli", "cmprb",
221 "cntlzd", "cntlzw", "cnttzd", "cnttzw", "crand", "crandc", "creqv",
222 "crnand", "crnor", "cror", "crorc", "crxor", "darn", "dcbf", "dcbst",
223 "dcbt", "dcbtst", "dcbz", "divd", "divde", "divdeo", "divdeu",
224 "divdeuo", "divdo", "divdu", "divduo", "divw", "divwe", "divweo",
225 "divweu", "divweuo", "divwo", "divwu", "divwuo", "eqv", "extsb",
226 "extsh", "extsw", "extswsli", "hrfid", "icbi", "icbt", "isel", "isync",
227 "lbarx", "lbz", "lbzu", "lbzux", "lbzx", "ld", "ldarx", "ldbrx",
228 "ldu", "ldux", "ldx", "lha", "lharx", "lhau", "lhaux", "lhax",
229 "lhbrx", "lhz", "lhzu", "lhzux", "lhzx", "lwa", "lwarx", "lwaux",
230 "lwax", "lwbrx", "lwz", "lwzcix", "lwzu", "lwzux", "lwzx", "mcrf", "mcrxr",
231 "mcrxrx", "mfcr/mfocrf", "mfmsr", "mfspr", "modsd", "modsw", "modud",
232 "moduw", "mtcrf/mtocrf", "mtmsr", "mtmsrd", "mtspr", "mulhd", "mulhdu",
233 "mulhw", "mulhwu", "mulld", "mulldo", "mulli", "mullw", "mullwo",
234 "nand", "neg", "nego", "nop", "nor", "or", "orc", "ori", "oris",
235 "popcntb", "popcntd", "popcntw", "prtyd", "prtyw", "rfid", "rldcl",
236 "rldcr", "rldic", "rldicl", "rldicr", "rldimi", "rlwimi", "rlwinm",
238 "setvl", # https://libre-soc.org/openpower/sv/setvl
239 "sim_cfg", "slbia", "sld", "slw", "srad", "sradi", "sraw",
240 "srawi", "srd", "srw", "stb", "stbcix", "stbcx", "stbu", "stbux", "stbx",
241 "std", "stdbrx", "stdcx", "stdu", "stdux", "stdx", "sth", "sthbrx", "sthcx",
242 "sthu", "sthux", "sthx", "stw", "stwbrx", "stwcx", "stwu", "stwux",
243 "stwx", "subf", "subfc", "subfco", "subfe", "subfeo", "subfic",
244 "subfme", "subfmeo", "subfo", "subfze", "subfzeo", "sync", "td",
245 "tdi", "tlbie", "tlbiel", "tw", "twi", "xor", "xori", "xoris",
248 # two-way lookup of instruction-to-index and vice-versa
251 for i
, insn
in enumerate(_insns
):
255 # Internal Operation numbering. Add new opcodes here (FPADD, FPMUL etc.)
260 OP_ILLEGAL
= 0 # important that this is zero (see power_decoder.py)
342 RS
= 4 # for some ALU/Logical operations
360 RS
= 13 # for shiftrot (M-Form)
367 RB
= 2 # for shiftrot (M-Form)
389 class LDSTMode(Enum
):
424 class CROutSel(Enum
):
433 # SPRs - Special-Purpose Registers. See V3.0B Figure 18 p971 and
434 # http://libre-riscv.org/openpower/isatables/sprs.csv
435 # http://bugs.libre-riscv.org/show_bug.cgi?id=261
437 def get_spr_enum(full_file
):
438 """get_spr_enum - creates an Enum of SPRs, dynamically
439 has the option to reduce the enum to a much shorter list.
440 this saves drastically on the size of the regfile
442 short_list
= {'PIDR', 'DAR', 'PRTBL', 'DSISR', 'SVSRR0', 'SVSTATE',
443 'SPRG0_priv', 'SPRG1_priv', 'SPRG2_priv', 'SPRG3_priv',
447 for row
in get_csv("sprs.csv"):
448 if full_file
or row
['SPR'] in short_list
:
451 spr_info
= namedtuple('spr_info', 'SPR priv_mtspr priv_mfspr length idx')
455 info
= spr_info(SPR
=row
['SPR'], priv_mtspr
=row
['priv_mtspr'],
456 priv_mfspr
=row
['priv_mfspr'], length
=int(row
['len']),
458 spr_dict
[int(row
['Idx'])] = info
459 spr_byname
[row
['SPR']] = info
460 fields
= [(row
['SPR'], int(row
['Idx'])) for row
in spr_csv
]
461 SPR
= Enum('SPR', fields
)
462 return SPR
, spr_dict
, spr_byname
464 SPRfull
, spr_dict
, spr_byname
= get_spr_enum(full_file
=True)
465 SPRreduced
, _
, _
= get_spr_enum(full_file
=False)
475 if __name__
== '__main__':
476 # find out what the heck is in SPR enum :)
477 print("sprs full", len(SPRfull
))
479 print("sprs reduced", len(SPRreduced
))
480 print(dir(SPRreduced
))
482 print(SPRfull
.__members
__['TAR'])
484 print(x
, x
.value
, str(x
), x
.name
)
486 print("function", Function
.ALU
.name
)