88279422834e6f5946161a8f75fb836e0b330133
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 SHAPE mode - TEMPORARY TEMPORARY TEMPORARY
122 SVRM
= 33 # Simple-V REMAP mode - TEMPORARY TEMPORARY TEMPORARY
125 # Simple-V svp64 fields https://libre-soc.org/openpower/sv/svp64/
149 Idx_1_2
= 5 # due to weird BA/BB for crops
153 class SVP64PredMode(Enum
):
160 class SVP64PredInt(Enum
):
172 class SVP64PredCR(Enum
):
184 class SVP64RMMode(Enum
):
194 class SVP64BCPredMode(Enum
):
201 class SVP64BCVLSETMode(Enum
):
207 # note that these are chosen to be exactly the same as
208 # SVP64 RM bit 4. ALL=1 => bit4=1
210 class SVP64BCGate(Enum
):
215 class SVP64BCCTRMode(Enum
):
222 class SVP64width(Enum
):
230 class SVP64subvl(Enum
):
238 class SVP64sat(Enum
):
245 class SVP64LDSTmode(Enum
):
253 # supported instructions: make sure to keep up-to-date with CSV files
254 # just like everything else
256 "NONE", "add", "addc", "addco", "adde", "addeo",
257 "addi", "addic", "addic.", "addis",
258 "addme", "addmeo", "addo", "addze", "addzeo",
260 "and", "andc", "andi.", "andis.",
262 "b", "bc", "bcctr", "bclr", "bctar",
266 "cmp", "cmpb", "cmpeqb", "cmpi", "cmpl", "cmpli", "cmprb",
267 "cntlzd", "cntlzw", "cnttzd", "cnttzw",
268 "crand", "crandc", "creqv",
269 "crnand", "crnor", "cror", "crorc", "crxor",
271 "dcbf", "dcbst", "dcbt", "dcbtst", "dcbz",
272 "divd", "divde", "divdeo", "divdeu",
273 "divdeuo", "divdo", "divdu", "divduo", "divw", "divwe", "divweo",
274 "divweu", "divweuo", "divwo", "divwu", "divwuo",
276 "extsb", "extsh", "extsw", "extswsli",
277 "fadd", "fadds", "fsub", "fsubs", # FP add / sub
278 "fcfids", "fcfidus", "fsqrts", "fres", "frsqrtes", # FP stuff
279 "fdmadds", # DCT FP 3-arg
280 "fmsubs", "fmadds", "fnmsubs", "fnmadds", # FP 3-arg
281 "ffadds", "ffsubs", "ffmuls", "ffdivs", # FFT FP 2-arg
282 "ffmsubs", "ffmadds", "ffnmsubs", "ffnmadds", # FFT FP 3-arg
283 "fmul", "fmuls", "fdiv", "fdivs", # FP mul / div
284 "fmr", "fabs", "fnabs", "fneg", "fcpsgn", # FP move/abs/neg
285 "fsins", "fcoss", # FP SIN/COS
286 "hrfid", "icbi", "icbt", "isel", "isync",
287 "lbarx", "lbz", "lbzu", "lbzux", "lbzx", # load byte
288 "ld", "ldarx", "ldbrx", "ldu", "ldux", "ldx", # load double
289 # "lbzbr", "lbzubr", # load byte SVP64 bit-reversed
290 # "ldbr", "ldubr", # load double SVP64 bit-reversed
291 "lfs", "lfsx", "lfsu", "lfsux", # FP load single
292 "lfd", "lfdx", "lfdu", "lfdux", "lfiwzx", "lfiwax", # FP load double
293 "lha", "lharx", "lhau", "lhaux", "lhax", # load half
294 "lhbrx", "lhz", "lhzu", "lhzux", "lhzx", # more load half
295 # "lhabr", "lhaubr", # load half SVP64 bit-reversed
296 # "lhzbr", "lhzubr", # more load half SVP64 bit-reversed
297 "lwa", "lwarx", "lwaux", "lwax", "lwbrx", # load word
298 "lwz", "lwzcix", "lwzu", "lwzux", "lwzx", # more load word
299 # "lwabr", # load word SVP64 bit-reversed
300 # "lwzbr", "lwzubr", # more load word SVP64 bit-reversed
301 "maddhd", "maddhdu", "maddld", # INT multiply-and-add
302 "mcrf", "mcrxr", "mcrxrx", "mfcr/mfocrf", # CR mvs
304 "modsd", "modsw", "modud", "moduw",
305 "mtcrf/mtocrf", "mtmsr", "mtmsrd", "mtspr",
306 "mulhd", "mulhdu", "mulhw", "mulhwu", "mulld", "mulldo",
307 "mulli", "mullw", "mullwo",
308 "nand", "neg", "nego",
310 "nor", "or", "orc", "ori", "oris",
311 "popcntb", "popcntd", "popcntw",
314 "rldcl", "rldcr", "rldic", "rldicl", "rldicr", "rldimi",
315 "rlwimi", "rlwinm", "rlwnm",
317 "setvl", # https://libre-soc.org/openpower/sv/setvl
318 "svremap", # https://libre-soc.org/openpower/sv/remap - TEMPORARY
319 "svshape", # https://libre-soc.org/openpower/sv/remap
320 "svstep", # https://libre-soc.org/openpower/sv/setvl
322 "slbia", "sld", "slw", "srad", "sradi",
323 "sraw", "srawi", "srd", "srw",
324 "stb", "stbcix", "stbcx", "stbu", "stbux", "stbx",
325 "std", "stdbrx", "stdcx", "stdu", "stdux", "stdx",
326 "stfs", "stfsx", "stfsu", "stfux", "stfsux", # FP store single
327 "stfd", "stfdx", "stfdu", "stfdux", "stfiwx", # FP store double
328 "sth", "sthbrx", "sthcx", "sthu", "sthux", "sthx",
329 "stw", "stwbrx", "stwcx", "stwu", "stwux", "stwx",
330 "subf", "subfc", "subfco", "subfe", "subfeo", "subfic",
331 "subfme", "subfmeo", "subfo", "subfze", "subfzeo",
337 "xor", "xori", "xoris",
340 # two-way lookup of instruction-to-index and vice-versa
343 for i
, insn
in enumerate(_insns
):
347 # must be long enough to cover all instructions
348 asmlen
= len(_insns
).bit_length()
350 # Internal Operation numbering. Add new opcodes here (FPADD, FPMUL etc.)
355 OP_ILLEGAL
= 0 # important that this is zero (see power_decoder.py)
429 OP_FPOP
= 77 # temporary: replace with actual ops
430 OP_FPOP_I
= 78 # temporary: replace with actual ops
448 RS
= 4 # for some ALU/Logical operations
468 RS
= 13 # for shiftrot (M-Form)
470 CONST_SVD
= 15 # for SVD-Form
471 CONST_SVDS
= 16 # for SVDS-Form
478 RB
= 2 # for shiftrot (M-Form)
481 RC
= 5 # for SVP64 bit-reverse LD/ST
482 RT
= 6 # for ternlog[i]
506 class LDSTMode(Enum
):
541 class CROutSel(Enum
):
550 # SPRs - Special-Purpose Registers. See V3.0B Figure 18 p971 and
551 # http://libre-riscv.org/openpower/isatables/sprs.csv
552 # http://bugs.libre-riscv.org/show_bug.cgi?id=261
554 def get_spr_enum(full_file
):
555 """get_spr_enum - creates an Enum of SPRs, dynamically
556 has the option to reduce the enum to a much shorter list.
557 this saves drastically on the size of the regfile
559 short_list
= {'PIDR', 'DAR', 'PRTBL', 'DSISR', 'SVSRR0', 'SVSTATE',
560 'SVSTATE0', 'SVSTATE1', 'SVSTATE2', 'SVSTATE3',
561 'SPRG0_priv', 'SPRG1_priv', 'SPRG2_priv', 'SPRG3_priv',
565 for row
in get_csv("sprs.csv"):
566 if full_file
or row
['SPR'] in short_list
:
569 spr_info
= namedtuple('spr_info', 'SPR priv_mtspr priv_mfspr length idx')
573 info
= spr_info(SPR
=row
['SPR'], priv_mtspr
=row
['priv_mtspr'],
574 priv_mfspr
=row
['priv_mfspr'], length
=int(row
['len']),
576 spr_dict
[int(row
['Idx'])] = info
577 spr_byname
[row
['SPR']] = info
578 fields
= [(row
['SPR'], int(row
['Idx'])) for row
in spr_csv
]
579 SPR
= Enum('SPR', fields
)
580 return SPR
, spr_dict
, spr_byname
583 SPRfull
, spr_dict
, spr_byname
= get_spr_enum(full_file
=True)
584 SPRreduced
, _
, _
= get_spr_enum(full_file
=False)
594 if __name__
== '__main__':
595 # find out what the heck is in SPR enum :)
596 print("sprs full", len(SPRfull
))
598 print("sprs reduced", len(SPRreduced
))
599 print(dir(SPRreduced
))
601 print(SPRfull
.__members
__['TAR'])
603 print("full", x
, x
.value
, str(x
), x
.name
)
605 print("reduced", x
, x
.value
, str(x
), x
.name
)
607 print("function", Function
.ALU
.name
)