4b94527392b8f2d24dceda93c84479eb1a5bb148
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
117 SVL
= 29 # Simple-V for setvl instruction
119 # Simple-V svp64 fields https://libre-soc.org/openpower/sv/svp64/
143 Idx_1_2
= 5 # due to weird BA/BB for crops
147 class SVP64PredMode(Enum
):
154 class SVP64PredInt(Enum
):
166 class SVP64PredCR(Enum
):
178 class SVP64RMMode(Enum
):
187 class SVP64width(Enum
):
195 class SVP64subvl(Enum
):
203 class SVP64sat(Enum
):
209 # supported instructions: make sure to keep up-to-date with CSV files
210 # just like everything else
212 "NONE", "add", "addc", "addco", "adde", "addeo",
213 "addi", "addic", "addic.", "addis",
214 "addme", "addmeo", "addo", "addze", "addzeo",
215 "and", "andc", "andi.", "andis.",
217 "b", "bc", "bcctr", "bclr", "bctar",
219 "cmp", "cmpb", "cmpeqb", "cmpi", "cmpl", "cmpli", "cmprb",
220 "cntlzd", "cntlzw", "cnttzd", "cnttzw",
221 "crand", "crandc", "creqv",
222 "crnand", "crnor", "cror", "crorc", "crxor",
224 "dcbf", "dcbst", "dcbt", "dcbtst", "dcbz",
225 "divd", "divde", "divdeo", "divdeu",
226 "divdeuo", "divdo", "divdu", "divduo", "divw", "divwe", "divweo",
227 "divweu", "divweuo", "divwo", "divwu", "divwuo",
229 "extsb", "extsh", "extsw", "extswsli",
230 "hrfid", "icbi", "icbt", "isel", "isync",
231 "lbarx", "lbz", "lbzu", "lbzux", "lbzx", # load byte
232 "ld", "ldarx", "ldbrx", "ldu", "ldux", "ldx", # load double
233 "lfs", "lfsx", "lfsu", "lfsux", # FP load single
234 "lfd", "lfdx", "lfdu", "lfdux", "lfiwzx", "lfiwax", # FP load double
235 "lha", "lharx", "lhau", "lhaux", "lhax", # load half
236 "lhbrx", "lhz", "lhzu", "lhzux", "lhzx", # more load half
237 "lwa", "lwarx", "lwaux", "lwax", "lwbrx", # load word
238 "lwz", "lwzcix", "lwzu", "lwzux", "lwzx", # more load word
239 "mcrf", "mcrxr", "mcrxrx", "mfcr/mfocrf", # CR mvs
241 "modsd", "modsw", "modud", "moduw",
242 "mtcrf/mtocrf", "mtmsr", "mtmsrd", "mtspr",
243 "mulhd", "mulhdu", "mulhw", "mulhwu", "mulld", "mulldo",
244 "mulli", "mullw", "mullwo",
245 "nand", "neg", "nego",
247 "nor", "or", "orc", "ori", "oris",
248 "popcntb", "popcntd", "popcntw",
251 "rldcl", "rldcr", "rldic", "rldicl", "rldicr", "rldimi",
252 "rlwimi", "rlwinm", "rlwnm",
254 "setvl", # https://libre-soc.org/openpower/sv/setvl
256 "slbia", "sld", "slw", "srad", "sradi",
257 "sraw", "srawi", "srd", "srw",
258 "stb", "stbcix", "stbcx", "stbu", "stbux", "stbx",
259 "std", "stdbrx", "stdcx", "stdu", "stdux", "stdx",
260 "sth", "sthbrx", "sthcx", "sthu", "sthux", "sthx",
261 "stw", "stwbrx", "stwcx", "stwu", "stwux", "stwx",
262 "subf", "subfc", "subfco", "subfe", "subfeo", "subfic",
263 "subfme", "subfmeo", "subfo", "subfze", "subfzeo",
268 "xor", "xori", "xoris",
271 # two-way lookup of instruction-to-index and vice-versa
274 for i
, insn
in enumerate(_insns
):
278 # Internal Operation numbering. Add new opcodes here (FPADD, FPMUL etc.)
283 OP_ILLEGAL
= 0 # important that this is zero (see power_decoder.py)
365 RS
= 4 # for some ALU/Logical operations
385 RS
= 13 # for shiftrot (M-Form)
393 RB
= 2 # for shiftrot (M-Form)
418 class LDSTMode(Enum
):
453 class CROutSel(Enum
):
462 # SPRs - Special-Purpose Registers. See V3.0B Figure 18 p971 and
463 # http://libre-riscv.org/openpower/isatables/sprs.csv
464 # http://bugs.libre-riscv.org/show_bug.cgi?id=261
466 def get_spr_enum(full_file
):
467 """get_spr_enum - creates an Enum of SPRs, dynamically
468 has the option to reduce the enum to a much shorter list.
469 this saves drastically on the size of the regfile
471 short_list
= {'PIDR', 'DAR', 'PRTBL', 'DSISR', 'SVSRR0', 'SVSTATE',
472 'SPRG0_priv', 'SPRG1_priv', 'SPRG2_priv', 'SPRG3_priv',
476 for row
in get_csv("sprs.csv"):
477 if full_file
or row
['SPR'] in short_list
:
480 spr_info
= namedtuple('spr_info', 'SPR priv_mtspr priv_mfspr length idx')
484 info
= spr_info(SPR
=row
['SPR'], priv_mtspr
=row
['priv_mtspr'],
485 priv_mfspr
=row
['priv_mfspr'], length
=int(row
['len']),
487 spr_dict
[int(row
['Idx'])] = info
488 spr_byname
[row
['SPR']] = info
489 fields
= [(row
['SPR'], int(row
['Idx'])) for row
in spr_csv
]
490 SPR
= Enum('SPR', fields
)
491 return SPR
, spr_dict
, spr_byname
493 SPRfull
, spr_dict
, spr_byname
= get_spr_enum(full_file
=True)
494 SPRreduced
, _
, _
= get_spr_enum(full_file
=False)
504 if __name__
== '__main__':
505 # find out what the heck is in SPR enum :)
506 print("sprs full", len(SPRfull
))
508 print("sprs reduced", len(SPRreduced
))
509 print(dir(SPRreduced
))
511 print(SPRfull
.__members
__['TAR'])
513 print("full", x
, x
.value
, str(x
), x
.name
)
515 print("reduced", x
, x
.value
, str(x
), x
.name
)
517 print("function", Function
.ALU
.name
)