b9099dc29b206660f1210da8c3b91942d2ab023f
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
121 SVM
= 32 # Simple-V REMAP mode - TEMPORARY TEMPORARY TEMPORARY
123 # Simple-V svp64 fields https://libre-soc.org/openpower/sv/svp64/
147 Idx_1_2
= 5 # due to weird BA/BB for crops
151 class SVP64PredMode(Enum
):
158 class SVP64PredInt(Enum
):
170 class SVP64PredCR(Enum
):
182 class SVP64RMMode(Enum
):
191 class SVP64width(Enum
):
199 class SVP64subvl(Enum
):
207 class SVP64sat(Enum
):
213 class SVP64LDSTmode(Enum
):
221 # supported instructions: make sure to keep up-to-date with CSV files
222 # just like everything else
224 "NONE", "add", "addc", "addco", "adde", "addeo",
225 "addi", "addic", "addic.", "addis",
226 "addme", "addmeo", "addo", "addze", "addzeo",
227 "and", "andc", "andi.", "andis.",
229 "b", "bc", "bcctr", "bclr", "bctar",
231 "cmp", "cmpb", "cmpeqb", "cmpi", "cmpl", "cmpli", "cmprb",
232 "cntlzd", "cntlzw", "cnttzd", "cnttzw",
233 "crand", "crandc", "creqv",
234 "crnand", "crnor", "cror", "crorc", "crxor",
236 "dcbf", "dcbst", "dcbt", "dcbtst", "dcbz",
237 "divd", "divde", "divdeo", "divdeu",
238 "divdeuo", "divdo", "divdu", "divduo", "divw", "divwe", "divweo",
239 "divweu", "divweuo", "divwo", "divwu", "divwuo",
241 "extsb", "extsh", "extsw", "extswsli",
242 "fadd", "fadds", "fsub", "fsubs", # FP add / sub
243 "fcfids", "fcfidus", "fsqrts", "fres", "frsqrtes", # FP stuff
244 "fmsubs", "fmadds", "fnmsubs", "fnmadds", # FP 3-arg
245 "ffadds", "ffsubs", "ffmuls", "ffdivs", # FFT FP 2-arg
246 "ffmsubs", "ffmadds", "ffnmsubs", "ffnmadds", # FFT FP 3-arg
247 "fmul", "fmuls", "fdiv", "fdivs", # FP mul / div
248 "fmr", "fabs", "fnabs", "fneg", "fcpsgn", # FP move/abs/neg
249 "hrfid", "icbi", "icbt", "isel", "isync",
250 "lbarx", "lbz", "lbzu", "lbzux", "lbzx", # load byte
251 "ld", "ldarx", "ldbrx", "ldu", "ldux", "ldx", # load double
252 #"lbzbr", "lbzubr", # load byte SVP64 bit-reversed
253 #"ldbr", "ldubr", # load double SVP64 bit-reversed
254 "lfs", "lfsx", "lfsu", "lfsux", # FP load single
255 "lfd", "lfdx", "lfdu", "lfdux", "lfiwzx", "lfiwax", # FP load double
256 "lha", "lharx", "lhau", "lhaux", "lhax", # load half
257 "lhbrx", "lhz", "lhzu", "lhzux", "lhzx", # more load half
258 #"lhabr", "lhaubr", # load half SVP64 bit-reversed
259 #"lhzbr", "lhzubr", # more load half SVP64 bit-reversed
260 "lwa", "lwarx", "lwaux", "lwax", "lwbrx", # load word
261 "lwz", "lwzcix", "lwzu", "lwzux", "lwzx", # more load word
262 #"lwabr", # load word SVP64 bit-reversed
263 #"lwzbr", "lwzubr", # more load word SVP64 bit-reversed
264 "maddhd", "maddhdu", "maddld", # INT multiply-and-add
265 "mcrf", "mcrxr", "mcrxrx", "mfcr/mfocrf", # CR mvs
267 "modsd", "modsw", "modud", "moduw",
268 "mtcrf/mtocrf", "mtmsr", "mtmsrd", "mtspr",
269 "mulhd", "mulhdu", "mulhw", "mulhwu", "mulld", "mulldo",
270 "mulli", "mullw", "mullwo",
271 "nand", "neg", "nego",
273 "nor", "or", "orc", "ori", "oris",
274 "popcntb", "popcntd", "popcntw",
277 "rldcl", "rldcr", "rldic", "rldicl", "rldicr", "rldimi",
278 "rlwimi", "rlwinm", "rlwnm",
280 "setvl", # https://libre-soc.org/openpower/sv/setvl
281 "svremap", # https://libre-soc.org/openpower/sv/remap - TEMPORARY
282 "svshape", # https://libre-soc.org/openpower/sv/remap
284 "slbia", "sld", "slw", "srad", "sradi",
285 "sraw", "srawi", "srd", "srw",
286 "stb", "stbcix", "stbcx", "stbu", "stbux", "stbx",
287 "std", "stdbrx", "stdcx", "stdu", "stdux", "stdx",
288 "stfs", "stfsx", "stfsu", "stfux", # FP store single
289 "stfd", "stfdx", "stfdu", "stfdux", "stfiwx", # FP store double
290 "sth", "sthbrx", "sthcx", "sthu", "sthux", "sthx",
291 "stw", "stwbrx", "stwcx", "stwu", "stwux", "stwx",
292 "subf", "subfc", "subfco", "subfe", "subfeo", "subfic",
293 "subfme", "subfmeo", "subfo", "subfze", "subfzeo",
298 "xor", "xori", "xoris",
301 # two-way lookup of instruction-to-index and vice-versa
304 for i
, insn
in enumerate(_insns
):
308 # must be long enough to cover all instructions
309 asmlen
= len(_insns
).bit_length()
311 # Internal Operation numbering. Add new opcodes here (FPADD, FPMUL etc.)
316 OP_ILLEGAL
= 0 # important that this is zero (see power_decoder.py)
390 OP_FPOP
= 77 # temporary: replace with actual ops
391 OP_FPOP_I
= 78 # temporary: replace with actual ops
402 RS
= 4 # for some ALU/Logical operations
422 RS
= 13 # for shiftrot (M-Form)
424 CONST_SVD
= 15 # for SVD-Form
425 CONST_SVDS
= 16 # for SVDS-Form
432 RB
= 2 # for shiftrot (M-Form)
435 RC
= 5 # for SVP64 bit-reverse LD/ST
459 class LDSTMode(Enum
):
494 class CROutSel(Enum
):
503 # SPRs - Special-Purpose Registers. See V3.0B Figure 18 p971 and
504 # http://libre-riscv.org/openpower/isatables/sprs.csv
505 # http://bugs.libre-riscv.org/show_bug.cgi?id=261
507 def get_spr_enum(full_file
):
508 """get_spr_enum - creates an Enum of SPRs, dynamically
509 has the option to reduce the enum to a much shorter list.
510 this saves drastically on the size of the regfile
512 short_list
= {'PIDR', 'DAR', 'PRTBL', 'DSISR', 'SVSRR0', 'SVSTATE',
513 'SVSTATE0', 'SVSTATE1', 'SVSTATE2', 'SVSTATE3',
514 'SPRG0_priv', 'SPRG1_priv', 'SPRG2_priv', 'SPRG3_priv',
518 for row
in get_csv("sprs.csv"):
519 if full_file
or row
['SPR'] in short_list
:
522 spr_info
= namedtuple('spr_info', 'SPR priv_mtspr priv_mfspr length idx')
526 info
= spr_info(SPR
=row
['SPR'], priv_mtspr
=row
['priv_mtspr'],
527 priv_mfspr
=row
['priv_mfspr'], length
=int(row
['len']),
529 spr_dict
[int(row
['Idx'])] = info
530 spr_byname
[row
['SPR']] = info
531 fields
= [(row
['SPR'], int(row
['Idx'])) for row
in spr_csv
]
532 SPR
= Enum('SPR', fields
)
533 return SPR
, spr_dict
, spr_byname
535 SPRfull
, spr_dict
, spr_byname
= get_spr_enum(full_file
=True)
536 SPRreduced
, _
, _
= get_spr_enum(full_file
=False)
546 if __name__
== '__main__':
547 # find out what the heck is in SPR enum :)
548 print("sprs full", len(SPRfull
))
550 print("sprs reduced", len(SPRreduced
))
551 print(dir(SPRreduced
))
553 print(SPRfull
.__members
__['TAR'])
555 print("full", x
, x
.value
, str(x
), x
.name
)
557 print("reduced", x
, x
.value
, str(x
), x
.name
)
559 print("function", Function
.ALU
.name
)