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
129 SVI
= 37 # Simple-V Index Mode
131 # Simple-V svp64 fields https://libre-soc.org/openpower/sv/svp64/
155 Idx_1_2
= 5 # due to weird BA/BB for crops
159 class SVP64PredMode(Enum
):
166 class SVP64PredInt(Enum
):
178 class SVP64PredCR(Enum
):
190 class SVP64RMMode(Enum
):
200 class SVP64BCPredMode(Enum
):
207 class SVP64BCVLSETMode(Enum
):
213 # note that these are chosen to be exactly the same as
214 # SVP64 RM bit 4. ALL=1 => bit4=1
216 class SVP64BCGate(Enum
):
221 class SVP64BCCTRMode(Enum
):
228 class SVP64width(Enum
):
236 class SVP64subvl(Enum
):
244 class SVP64sat(Enum
):
251 class SVP64LDSTmode(Enum
):
259 # supported instructions: make sure to keep up-to-date with CSV files
260 # just like everything else
262 "NONE", "add", "addc", "addco", "adde", "addeo",
263 "addi", "addic", "addic.", "addis",
264 "addme", "addmeo", "addo", "addze", "addzeo",
266 "and", "andc", "andi.", "andis.",
268 "absdu", "absds", # AV bitmanip
269 "absdacs", "absdacu", # AV bitmanip
270 "avgadd", # AV bitmanip
271 "b", "bc", "bcctr", "bclr", "bctar",
272 "bmask", # AV bitmanip
276 "cmp", "cmpb", "cmpeqb", "cmpi", "cmpl", "cmpli", "cmprb",
277 "cntlzd", "cntlzw", "cnttzd", "cnttzw",
278 "cprop", # AV bitmanip
279 "crand", "crandc", "creqv",
280 "crnand", "crnor", "cror", "crorc", "crxor",
282 "dcbf", "dcbst", "dcbt", "dcbtst", "dcbz",
283 "divd", "divde", "divdeo", "divdeu",
284 "divdeuo", "divdo", "divdu", "divduo", "divw", "divwe", "divweo",
285 "divweu", "divweuo", "divwo", "divwu", "divwuo",
287 "extsb", "extsh", "extsw", "extswsli",
288 "fadd", "fadds", "fsub", "fsubs", # FP add / sub
289 "fcfids", "fcfidus", "fsqrts", "fres", "frsqrtes", # FP stuff
290 "fdmadds", # DCT FP 3-arg
291 "fmsubs", "fmadds", "fnmsubs", "fnmadds", # FP 3-arg
292 "ffadds", "ffsubs", "ffmuls", "ffdivs", # FFT FP 2-arg
293 "ffmsubs", "ffmadds", "ffnmsubs", "ffnmadds", # FFT FP 3-arg
294 "fmul", "fmuls", "fdiv", "fdivs", # FP mul / div
295 "fmr", "fabs", "fnabs", "fneg", "fcpsgn", # FP move/abs/neg
296 "fsins", "fcoss", # FP SIN/COS
297 'grev', 'grev.', 'grevi', 'grevi.',
298 'grevw', 'grevw.', 'grevwi', 'grevwi.',
299 "hrfid", "icbi", "icbt", "isel", "isync",
300 "lbarx", "lbz", "lbzcix", "lbzu", "lbzux", "lbzx", # load byte
301 "ld", "ldarx", "ldbrx", "ldu", "ldux", "ldx", # load double
302 # "lbzbr", "lbzubr", # load byte SVP64 bit-reversed
303 # "ldbr", "ldubr", # load double SVP64 bit-reversed
304 "lfs", "lfsx", "lfsu", "lfsux", # FP load single
305 "lfd", "lfdx", "lfdu", "lfdux", "lfiwzx", "lfiwax", # FP load double
306 "lha", "lharx", "lhau", "lhaux", "lhax", # load half
307 "lhbrx", "lhz", "lhzu", "lhzux", "lhzx", # more load half
308 # "lhabr", "lhaubr", # load half SVP64 bit-reversed
309 # "lhzbr", "lhzubr", # more load half SVP64 bit-reversed
310 "lwa", "lwarx", "lwaux", "lwax", "lwbrx", # load word
311 "lwz", "lwzcix", "lwzu", "lwzux", "lwzx", # more load word
312 # "lwabr", # load word SVP64 bit-reversed
313 # "lwzbr", "lwzubr", # more load word SVP64 bit-reversed
314 "maddhd", "maddhdu", "maddld", # INT multiply-and-add
315 "mcrf", "mcrxr", "mcrxrx", "mfcr/mfocrf", # CR mvs
317 "mins", "maxs", "minu", "maxu", # AV bitmanip
318 "modsd", "modsw", "modud", "moduw",
319 "mtcrf/mtocrf", "mtmsr", "mtmsrd", "mtspr",
320 "mulhd", "mulhdu", "mulhw", "mulhwu", "mulld", "mulldo",
321 "mulli", "mullw", "mullwo",
322 "nand", "neg", "nego",
324 "nor", "or", "orc", "ori", "oris",
325 "popcntb", "popcntd", "popcntw",
328 "rldcl", "rldcr", "rldic", "rldicl", "rldicr", "rldimi",
329 "rlwimi", "rlwinm", "rlwnm",
331 "setvl", # https://libre-soc.org/openpower/sv/setvl
332 "svindex", # https://libre-soc.org/openpower/sv/remap
333 "svremap", # https://libre-soc.org/openpower/sv/remap - TEMPORARY
334 "svshape", # https://libre-soc.org/openpower/sv/remap
335 "svstep", # https://libre-soc.org/openpower/sv/setvl
337 "slbia", "sld", "slw", "srad", "sradi",
338 "sraw", "srawi", "srd", "srw",
339 "stb", "stbcix", "stbcx", "stbu", "stbux", "stbx",
340 "std", "stdbrx", "stdcx", "stdu", "stdux", "stdx",
341 "stfs", "stfsx", "stfsu", "stfux", "stfsux", # FP store single
342 "stfd", "stfdx", "stfdu", "stfdux", "stfiwx", # FP store double
343 "sth", "sthbrx", "sthcx", "sthu", "sthux", "sthx",
344 "stw", "stwbrx", "stwcx", "stwu", "stwux", "stwx",
345 "subf", "subfc", "subfco", "subfe", "subfeo", "subfic",
346 "subfme", "subfmeo", "subfo", "subfze", "subfzeo",
350 "tlbie", "tlbiel", "tlbsync",
353 "xor", "xori", "xoris",
356 # two-way lookup of instruction-to-index and vice-versa
359 for i
, insn
in enumerate(_insns
):
363 # must be long enough to cover all instructions
364 asmlen
= len(_insns
).bit_length()
366 # Internal Operation numbering. Add new opcodes here (FPADD, FPMUL etc.)
371 OP_ILLEGAL
= 0 # important that this is zero (see power_decoder.py)
445 OP_FPOP
= 77 # temporary: replace with actual ops
446 OP_FPOP_I
= 78 # temporary: replace with actual ops
472 RS
= 4 # for some ALU/Logical operations
492 RS
= 13 # for shiftrot (M-Form)
494 CONST_SVD
= 15 # for SVD-Form
495 CONST_SVDS
= 16 # for SVDS-Form
503 RB
= 2 # for shiftrot (M-Form)
506 RC
= 5 # for SVP64 bit-reverse LD/ST
507 RT
= 6 # for ternlog[i]
531 class LDSTMode(Enum
):
566 class CROutSel(Enum
):
575 # SPRs - Special-Purpose Registers. See V3.0B Figure 18 p971 and
576 # http://libre-riscv.org/openpower/isatables/sprs.csv
577 # http://bugs.libre-riscv.org/show_bug.cgi?id=261
578 # http://bugs.libre-riscv.org/show_bug.cgi?id=859 - KAIVB
580 def get_spr_enum(full_file
):
581 """get_spr_enum - creates an Enum of SPRs, dynamically
582 has the option to reduce the enum to a much shorter list.
583 this saves drastically on the size of the regfile
585 short_list
= {'PIDR', 'DAR', 'PRTBL', 'DSISR', 'SVSRR0', 'SVSTATE',
586 'SVSTATE0', 'SVSTATE1', 'SVSTATE2', 'SVSTATE3',
587 'SPRG0_priv', 'SPRG1_priv', 'SPRG2_priv', 'SPRG3_priv',
588 'SPRG0', 'SPRG1', 'SPRG2', 'SPRG3', 'KAIVB',
589 # hmmm should not be including these, they are FAST regs
590 'CTR', 'LR', 'TAR', 'SRR0', 'SRR1', 'XER', 'DEC', 'TB', 'TBU',
591 'HSRR0', 'HSRR1', 'HSPRG0', 'HSPRG1',
594 for row
in get_csv("sprs.csv"):
595 if full_file
or row
['SPR'] in short_list
:
598 spr_info
= namedtuple('spr_info', 'SPR priv_mtspr priv_mfspr length idx')
602 info
= spr_info(SPR
=row
['SPR'], priv_mtspr
=row
['priv_mtspr'],
603 priv_mfspr
=row
['priv_mfspr'], length
=int(row
['len']),
605 spr_dict
[int(row
['Idx'])] = info
606 spr_byname
[row
['SPR']] = info
607 fields
= [(row
['SPR'], int(row
['Idx'])) for row
in spr_csv
]
608 SPR
= Enum('SPR', fields
)
609 return SPR
, spr_dict
, spr_byname
612 SPRfull
, spr_dict
, spr_byname
= get_spr_enum(full_file
=True)
613 SPRreduced
, _
, _
= get_spr_enum(full_file
=False)
623 MSRSpec
= namedtuple("MSRSpec", ["dr", "pr", "sf"])
625 if __name__
== '__main__':
626 # find out what the heck is in SPR enum :)
627 print("sprs full", len(SPRfull
))
629 print("sprs reduced", len(SPRreduced
))
630 print(dir(SPRreduced
))
632 print(SPRfull
.__members
__['TAR'])
634 print("full", x
, x
.value
, str(x
), x
.name
)
636 print("reduced", x
, x
.value
, str(x
), x
.name
)
638 print("function", Function
.ALU
.name
)