bf5738997b4b08eae72f732b458e0fd24f73cb6f
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
119 SVD
= 30 # Simple-V for LD/ST bit-reverse, variant of D-Form
120 SVDS
= 31 # Simple-V for LD/ST bit-reverse, variant of DS-Form
122 # Simple-V svp64 fields https://libre-soc.org/openpower/sv/svp64/
146 Idx_1_2
= 5 # due to weird BA/BB for crops
150 class SVP64PredMode(Enum
):
157 class SVP64PredInt(Enum
):
169 class SVP64PredCR(Enum
):
181 class SVP64RMMode(Enum
):
190 class SVP64width(Enum
):
198 class SVP64subvl(Enum
):
206 class SVP64sat(Enum
):
212 class SVP64LDSTmode(Enum
):
220 # supported instructions: make sure to keep up-to-date with CSV files
221 # just like everything else
223 "NONE", "add", "addc", "addco", "adde", "addeo",
224 "addi", "addic", "addic.", "addis",
225 "addme", "addmeo", "addo", "addze", "addzeo",
226 "and", "andc", "andi.", "andis.",
228 "b", "bc", "bcctr", "bclr", "bctar",
230 "cmp", "cmpb", "cmpeqb", "cmpi", "cmpl", "cmpli", "cmprb",
231 "cntlzd", "cntlzw", "cnttzd", "cnttzw",
232 "crand", "crandc", "creqv",
233 "crnand", "crnor", "cror", "crorc", "crxor",
235 "dcbf", "dcbst", "dcbt", "dcbtst", "dcbz",
236 "divd", "divde", "divdeo", "divdeu",
237 "divdeuo", "divdo", "divdu", "divduo", "divw", "divwe", "divweo",
238 "divweu", "divweuo", "divwo", "divwu", "divwuo",
240 "extsb", "extsh", "extsw", "extswsli",
241 "fadd", "fadds", "fsub", "fsubs", # FP add / sub
242 "fcfids", "fcfidus", "fsqrts", "fres", "frsqrtes", # FP stuff
243 "fmsubs", "fmadds", "fnmsubs", "fnmadds", # FP 3-arg
244 "ffmsubs", "ffmadds", "ffnmsubs", "ffnmadds", # FFT FP 3-arg
245 "fmul", "fmuls", "fdiv", "fdivs", # FP mul / div
246 "fmr", "fabs", "fnabs", "fneg", "fcpsgn", # FP move/abs/neg
247 "hrfid", "icbi", "icbt", "isel", "isync",
248 "lbarx", "lbz", "lbzu", "lbzux", "lbzx", # load byte
249 "ld", "ldarx", "ldbrx", "ldu", "ldux", "ldx", # load double
250 #"lbzbr", "lbzubr", # load byte SVP64 bit-reversed
251 #"ldbr", "ldubr", # load double SVP64 bit-reversed
252 "lfs", "lfsx", "lfsu", "lfsux", # FP load single
253 "lfd", "lfdx", "lfdu", "lfdux", "lfiwzx", "lfiwax", # FP load double
254 "lha", "lharx", "lhau", "lhaux", "lhax", # load half
255 "lhbrx", "lhz", "lhzu", "lhzux", "lhzx", # more load half
256 #"lhabr", "lhaubr", # load half SVP64 bit-reversed
257 #"lhzbr", "lhzubr", # more load half SVP64 bit-reversed
258 "lwa", "lwarx", "lwaux", "lwax", "lwbrx", # load word
259 "lwz", "lwzcix", "lwzu", "lwzux", "lwzx", # more load word
260 #"lwabr", # load word SVP64 bit-reversed
261 #"lwzbr", "lwzubr", # more load word SVP64 bit-reversed
262 "maddhd", "maddhdu", "maddld", # INT multiply-and-add
263 "mcrf", "mcrxr", "mcrxrx", "mfcr/mfocrf", # CR mvs
265 "modsd", "modsw", "modud", "moduw",
266 "mtcrf/mtocrf", "mtmsr", "mtmsrd", "mtspr",
267 "mulhd", "mulhdu", "mulhw", "mulhwu", "mulld", "mulldo",
268 "mulli", "mullw", "mullwo",
269 "nand", "neg", "nego",
271 "nor", "or", "orc", "ori", "oris",
272 "popcntb", "popcntd", "popcntw",
275 "rldcl", "rldcr", "rldic", "rldicl", "rldicr", "rldimi",
276 "rlwimi", "rlwinm", "rlwnm",
278 "setvl", # https://libre-soc.org/openpower/sv/setvl
280 "slbia", "sld", "slw", "srad", "sradi",
281 "sraw", "srawi", "srd", "srw",
282 "stb", "stbcix", "stbcx", "stbu", "stbux", "stbx",
283 "std", "stdbrx", "stdcx", "stdu", "stdux", "stdx",
284 "stfs", "stfsx", "stfsu", "stfux", # FP store single
285 "stfd", "stfdx", "stfdu", "stfdux", "stfiwx", # FP store double
286 "sth", "sthbrx", "sthcx", "sthu", "sthux", "sthx",
287 "stw", "stwbrx", "stwcx", "stwu", "stwux", "stwx",
288 "subf", "subfc", "subfco", "subfe", "subfeo", "subfic",
289 "subfme", "subfmeo", "subfo", "subfze", "subfzeo",
294 "xor", "xori", "xoris",
297 # two-way lookup of instruction-to-index and vice-versa
300 for i
, insn
in enumerate(_insns
):
304 # Internal Operation numbering. Add new opcodes here (FPADD, FPMUL etc.)
309 OP_ILLEGAL
= 0 # important that this is zero (see power_decoder.py)
383 OP_FPOP
= 77 # temporary: replace with actual ops
384 OP_FPOP_I
= 78 # temporary: replace with actual ops
394 RS
= 4 # for some ALU/Logical operations
414 RS
= 13 # for shiftrot (M-Form)
416 CONST_SVD
= 15 # for SVD-Form
417 CONST_SVDS
= 16 # for SVDS-Form
424 RB
= 2 # for shiftrot (M-Form)
427 RC
= 5 # for SVP64 bit-reverse LD/ST
451 class LDSTMode(Enum
):
486 class CROutSel(Enum
):
495 # SPRs - Special-Purpose Registers. See V3.0B Figure 18 p971 and
496 # http://libre-riscv.org/openpower/isatables/sprs.csv
497 # http://bugs.libre-riscv.org/show_bug.cgi?id=261
499 def get_spr_enum(full_file
):
500 """get_spr_enum - creates an Enum of SPRs, dynamically
501 has the option to reduce the enum to a much shorter list.
502 this saves drastically on the size of the regfile
504 short_list
= {'PIDR', 'DAR', 'PRTBL', 'DSISR', 'SVSRR0', 'SVSTATE',
505 'SPRG0_priv', 'SPRG1_priv', 'SPRG2_priv', 'SPRG3_priv',
509 for row
in get_csv("sprs.csv"):
510 if full_file
or row
['SPR'] in short_list
:
513 spr_info
= namedtuple('spr_info', 'SPR priv_mtspr priv_mfspr length idx')
517 info
= spr_info(SPR
=row
['SPR'], priv_mtspr
=row
['priv_mtspr'],
518 priv_mfspr
=row
['priv_mfspr'], length
=int(row
['len']),
520 spr_dict
[int(row
['Idx'])] = info
521 spr_byname
[row
['SPR']] = info
522 fields
= [(row
['SPR'], int(row
['Idx'])) for row
in spr_csv
]
523 SPR
= Enum('SPR', fields
)
524 return SPR
, spr_dict
, spr_byname
526 SPRfull
, spr_dict
, spr_byname
= get_spr_enum(full_file
=True)
527 SPRreduced
, _
, _
= get_spr_enum(full_file
=False)
537 if __name__
== '__main__':
538 # find out what the heck is in SPR enum :)
539 print("sprs full", len(SPRfull
))
541 print("sprs reduced", len(SPRreduced
))
542 print(dir(SPRreduced
))
544 print(SPRfull
.__members
__['TAR'])
546 print("full", x
, x
.value
, str(x
), x
.name
)
548 print("reduced", x
, x
.value
, str(x
), x
.name
)
550 print("function", Function
.ALU
.name
)