5b9c888a25f9e8a1d888f856a11d6e94eae8c9df
1 # SPDX-License-Identifier: LGPL-3-or-later
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 """gets a not-entirely-csv-file-formatted database, which allows comments
40 file_path
= find_wiki_file(name
)
41 with
open(file_path
, 'r') as csvfile
:
42 csvfile
= filter(lambda row
: row
[0] !='#', csvfile
) # strip "#..."
43 reader
= csv
.DictReader(csvfile
)
47 # names of the fields in the tables that don't correspond to an enum
48 single_bit_flags
= ['inv A', 'inv out',
49 'cry out', 'BR', 'sgn ext', 'rsrv', '32b',
50 'sgn', 'lk', 'sgl pipe']
52 # default values for fields in the table
53 default_values
= {'unit': "NONE", 'internal op': "OP_ILLEGAL",
54 'in1': "RA", 'in2': 'NONE', 'in3': 'NONE', 'out': 'NONE',
58 'rc': 'NONE', 'cry in': 'ZERO', 'form': 'NONE'}
61 def get_signal_name(name
):
64 return name
.lower().replace(' ', '_')
66 # this corresponds to which Function Unit (pipeline-with-Reservation-Stations)
67 # is to process and guard the operation. they are roughly divided by having
68 # the same register input/output signature (X-Form, etc.)
85 SV
= 1 << 12 # Simple-V https://libre-soc.org/openpower/sv
121 SVL
= 29 # Simple-V for setvl instruction
122 SVD
= 30 # Simple-V for LD/ST bit-reverse, variant of D-Form
123 SVDS
= 31 # Simple-V for LD/ST bit-reverse, variant of DS-Form
124 SVM
= 32 # Simple-V SHAPE mode - TEMPORARY TEMPORARY TEMPORARY
125 SVRM
= 33 # Simple-V REMAP mode - TEMPORARY TEMPORARY TEMPORARY
129 # Simple-V svp64 fields https://libre-soc.org/openpower/sv/svp64/
153 Idx_1_2
= 5 # due to weird BA/BB for crops
157 class SVP64PredMode(Enum
):
164 class SVP64PredInt(Enum
):
176 class SVP64PredCR(Enum
):
188 class SVP64RMMode(Enum
):
198 class SVP64BCPredMode(Enum
):
205 class SVP64BCVLSETMode(Enum
):
211 # note that these are chosen to be exactly the same as
212 # SVP64 RM bit 4. ALL=1 => bit4=1
214 class SVP64BCGate(Enum
):
219 class SVP64BCCTRMode(Enum
):
226 class SVP64width(Enum
):
234 class SVP64subvl(Enum
):
242 class SVP64sat(Enum
):
249 class SVP64LDSTmode(Enum
):
257 # supported instructions: make sure to keep up-to-date with CSV files
258 # just like everything else
260 "NONE", "add", "addc", "addco", "adde", "addeo",
261 "addi", "addic", "addic.", "addis",
262 "addme", "addmeo", "addo", "addze", "addzeo",
264 "and", "andc", "andi.", "andis.",
266 "absdu", "absds", # AV bitmanip
267 "absdacs", "absdacu", # AV bitmanip
268 "avgadd", # AV bitmanip
269 "b", "bc", "bcctr", "bclr", "bctar",
273 "cmp", "cmpb", "cmpeqb", "cmpi", "cmpl", "cmpli", "cmprb",
274 "cntlzd", "cntlzw", "cnttzd", "cnttzw",
275 "cprop", # AV bitmanip
276 "crand", "crandc", "creqv",
277 "crnand", "crnor", "cror", "crorc", "crxor",
279 "dcbf", "dcbst", "dcbt", "dcbtst", "dcbz",
280 "divd", "divde", "divdeo", "divdeu",
281 "divdeuo", "divdo", "divdu", "divduo", "divw", "divwe", "divweo",
282 "divweu", "divweuo", "divwo", "divwu", "divwuo",
284 "extsb", "extsh", "extsw", "extswsli",
285 "fadd", "fadds", "fsub", "fsubs", # FP add / sub
286 "fcfids", "fcfidus", "fsqrts", "fres", "frsqrtes", # FP stuff
287 "fdmadds", # DCT FP 3-arg
288 "fmsubs", "fmadds", "fnmsubs", "fnmadds", # FP 3-arg
289 "ffadds", "ffsubs", "ffmuls", "ffdivs", # FFT FP 2-arg
290 "ffmsubs", "ffmadds", "ffnmsubs", "ffnmadds", # FFT FP 3-arg
291 "fmul", "fmuls", "fdiv", "fdivs", # FP mul / div
292 "fmr", "fabs", "fnabs", "fneg", "fcpsgn", # FP move/abs/neg
293 "fsins", "fcoss", # FP SIN/COS
294 'grev', 'grev.', 'grevi', 'grevi.',
295 'grevw', 'grevw.', 'grevwi', 'grevwi.',
296 "hrfid", "icbi", "icbt", "isel", "isync",
297 "lbarx", "lbz", "lbzcix", "lbzu", "lbzux", "lbzx", # load byte
298 "ld", "ldarx", "ldbrx", "ldu", "ldux", "ldx", # load double
299 # "lbzbr", "lbzubr", # load byte SVP64 bit-reversed
300 # "ldbr", "ldubr", # load double SVP64 bit-reversed
301 "lfs", "lfsx", "lfsu", "lfsux", # FP load single
302 "lfd", "lfdx", "lfdu", "lfdux", "lfiwzx", "lfiwax", # FP load double
303 "lha", "lharx", "lhau", "lhaux", "lhax", # load half
304 "lhbrx", "lhz", "lhzu", "lhzux", "lhzx", # more load half
305 # "lhabr", "lhaubr", # load half SVP64 bit-reversed
306 # "lhzbr", "lhzubr", # more load half SVP64 bit-reversed
307 "lwa", "lwarx", "lwaux", "lwax", "lwbrx", # load word
308 "lwz", "lwzcix", "lwzu", "lwzux", "lwzx", # more load word
309 # "lwabr", # load word SVP64 bit-reversed
310 # "lwzbr", "lwzubr", # more load word SVP64 bit-reversed
311 "maddhd", "maddhdu", "maddld", # INT multiply-and-add
312 "mcrf", "mcrxr", "mcrxrx", "mfcr/mfocrf", # CR mvs
314 "mins", "maxs", "minu", "maxu", # AV bitmanip
315 "modsd", "modsw", "modud", "moduw",
316 "mtcrf/mtocrf", "mtmsr", "mtmsrd", "mtspr",
317 "mulhd", "mulhdu", "mulhw", "mulhwu", "mulld", "mulldo",
318 "mulli", "mullw", "mullwo",
319 "nand", "neg", "nego",
321 "nor", "or", "orc", "ori", "oris",
322 "popcntb", "popcntd", "popcntw",
325 "rldcl", "rldcr", "rldic", "rldicl", "rldicr", "rldimi",
326 "rlwimi", "rlwinm", "rlwnm",
328 "setvl", # https://libre-soc.org/openpower/sv/setvl
329 "svremap", # https://libre-soc.org/openpower/sv/remap - TEMPORARY
330 "svshape", # https://libre-soc.org/openpower/sv/remap
331 "svstep", # https://libre-soc.org/openpower/sv/setvl
333 "slbia", "sld", "slw", "srad", "sradi",
334 "sraw", "srawi", "srd", "srw",
335 "stb", "stbcix", "stbcx", "stbu", "stbux", "stbx",
336 "std", "stdbrx", "stdcx", "stdu", "stdux", "stdx",
337 "stfs", "stfsx", "stfsu", "stfux", "stfsux", # FP store single
338 "stfd", "stfdx", "stfdu", "stfdux", "stfiwx", # FP store double
339 "sth", "sthbrx", "sthcx", "sthu", "sthux", "sthx",
340 "stw", "stwbrx", "stwcx", "stwu", "stwux", "stwx",
341 "subf", "subfc", "subfco", "subfe", "subfeo", "subfic",
342 "subfme", "subfmeo", "subfo", "subfze", "subfzeo",
346 "tlbie", "tlbiel", "tlbsync",
349 "xor", "xori", "xoris",
352 # two-way lookup of instruction-to-index and vice-versa
355 for i
, insn
in enumerate(_insns
):
359 # must be long enough to cover all instructions
360 asmlen
= len(_insns
).bit_length()
362 # Internal Operation numbering. Add new opcodes here (FPADD, FPMUL etc.)
367 OP_ILLEGAL
= 0 # important that this is zero (see power_decoder.py)
441 OP_FPOP
= 77 # temporary: replace with actual ops
442 OP_FPOP_I
= 78 # temporary: replace with actual ops
466 RS
= 4 # for some ALU/Logical operations
486 RS
= 13 # for shiftrot (M-Form)
488 CONST_SVD
= 15 # for SVD-Form
489 CONST_SVDS
= 16 # for SVDS-Form
497 RB
= 2 # for shiftrot (M-Form)
500 RC
= 5 # for SVP64 bit-reverse LD/ST
501 RT
= 6 # for ternlog[i]
525 class LDSTMode(Enum
):
560 class CROutSel(Enum
):
569 # SPRs - Special-Purpose Registers. See V3.0B Figure 18 p971 and
570 # http://libre-riscv.org/openpower/isatables/sprs.csv
571 # http://bugs.libre-riscv.org/show_bug.cgi?id=261
572 # http://bugs.libre-riscv.org/show_bug.cgi?id=859 - KAIVB
574 def get_spr_enum(full_file
):
575 """get_spr_enum - creates an Enum of SPRs, dynamically
576 has the option to reduce the enum to a much shorter list.
577 this saves drastically on the size of the regfile
579 short_list
= {'PIDR', 'DAR', 'PRTBL', 'DSISR', 'SVSRR0', 'SVSTATE',
580 'SVSTATE0', 'SVSTATE1', 'SVSTATE2', 'SVSTATE3',
581 'SPRG0_priv', 'SPRG1_priv', 'SPRG2_priv', 'SPRG3_priv',
582 'SPRG0', 'SPRG1', 'SPRG2', 'SPRG3', 'KAIVB',
583 # hmmm should not be including these, they are FAST regs
584 'CTR', 'LR', 'TAR', 'SRR0', 'SRR1', 'XER', 'DEC', 'TB', 'TBU',
585 'HSRR0', 'HSRR1', 'HSPRG0', 'HSPRG1',
588 for row
in get_csv("sprs.csv"):
589 if full_file
or row
['SPR'] in short_list
:
592 spr_info
= namedtuple('spr_info', 'SPR priv_mtspr priv_mfspr length idx')
596 info
= spr_info(SPR
=row
['SPR'], priv_mtspr
=row
['priv_mtspr'],
597 priv_mfspr
=row
['priv_mfspr'], length
=int(row
['len']),
599 spr_dict
[int(row
['Idx'])] = info
600 spr_byname
[row
['SPR']] = info
601 fields
= [(row
['SPR'], int(row
['Idx'])) for row
in spr_csv
]
602 SPR
= Enum('SPR', fields
)
603 return SPR
, spr_dict
, spr_byname
606 SPRfull
, spr_dict
, spr_byname
= get_spr_enum(full_file
=True)
607 SPRreduced
, _
, _
= get_spr_enum(full_file
=False)
617 MSRSpec
= namedtuple("MSRSpec", ["dr", "pr", "sf"])
619 if __name__
== '__main__':
620 # find out what the heck is in SPR enum :)
621 print("sprs full", len(SPRfull
))
623 print("sprs reduced", len(SPRreduced
))
624 print(dir(SPRreduced
))
626 print(SPRfull
.__members
__['TAR'])
628 print("full", x
, x
.value
, str(x
), x
.name
)
630 print("reduced", x
, x
.value
, str(x
), x
.name
)
632 print("function", Function
.ALU
.name
)