bd8dfd1880adb20efe79ba396ed6709a899426e5
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
24 from os
.path
import dirname
, join
25 from collections
import namedtuple
30 filedir
= os
.path
.dirname(os
.path
.abspath(__file__
))
31 basedir
= dirname(dirname(dirname(filedir
)))
32 tabledir
= join(basedir
, 'openpower')
33 isatables
= join(tabledir
, 'isatables')
34 #print ("find_wiki_dir", isatables)
38 def find_wiki_file(name
):
39 return join(find_wiki_dir(), name
)
43 """gets a not-entirely-csv-file-formatted database, which allows comments
45 file_path
= find_wiki_file(name
)
46 with
open(file_path
, 'r') as csvfile
:
47 csvfile
= filter(lambda row
: row
[0] !='#', csvfile
) # strip "#..."
48 reader
= csv
.DictReader(csvfile
)
52 # names of the fields in the tables that don't correspond to an enum
53 single_bit_flags
= ['inv A', 'inv out',
54 'cry out', 'BR', 'sgn ext', 'rsrv', '32b',
55 'sgn', 'lk', 'sgl pipe']
57 # default values for fields in the table
58 default_values
= {'unit': "NONE", 'internal op': "OP_ILLEGAL",
59 'in1': "RA", 'in2': 'NONE', 'in3': 'NONE', 'out': 'NONE',
63 'rc': 'NONE', 'cry in': 'ZERO', 'form': 'NONE'}
66 def get_signal_name(name
):
69 return name
.lower().replace(' ', '_')
74 def _missing_(cls
, value
):
75 if isinstance(value
, str):
83 keys
= {item
.name
:item
for item
in cls
}
84 values
= {item
.value
:item
for item
in cls
}
85 item
= keys
.get(value
, values
.get(value
))
87 raise ValueError(value
)
91 # this corresponds to which Function Unit (pipeline-with-Reservation-Stations)
92 # is to process and guard the operation. they are roughly divided by having
93 # the same register input/output signature (X-Form, etc.)
110 SV
= 1 << 12 # Simple-V https://libre-soc.org/openpower/sv
114 @functools.lru_cache(maxsize
=None)
117 value
= int(self
.value
)
123 desc
= f
"(1 << {counter})"
126 return f
"<{self.__class__.__name__}.{self.name}: {desc}>"
160 SVL
= 29 # Simple-V for setvl instruction
161 SVD
= 30 # Simple-V for LD/ST bit-reverse, variant of D-Form
162 SVDS
= 31 # Simple-V for LD/ST bit-reverse, variant of DS-Form
163 SVM
= 32 # Simple-V SHAPE mode
164 SVM2
= 33 # Simple-V SHAPE2 mode - fits into SVM
165 SVRM
= 34 # Simple-V REMAP mode
169 SVI
= 38 # Simple-V Index Mode
174 # Simple-V svp64 fields https://libre-soc.org/openpower/sv/svp64/
192 def _missing_(cls
, value
):
193 return {"1P": SVPtype
.P1
, "2P": SVPtype
.P2
}[value
]
210 Idx_1_2
= 5 # due to weird BA/BB for crops
212 # Backward compatibility
216 class SVExtraRegType(Enum
):
222 class SVExtraReg(Enum
):
251 def _missing_(cls
, value
):
253 In1Sel
, In2Sel
, In3Sel
, CRInSel
,
256 if isinstance(value
, selectors
):
257 return cls
.__members
__.get(value
.name
, cls
.NONE
)
258 return super()._missing
_(value
)
262 class SVP64PredMode(Enum
):
269 class SVP64PredInt(Enum
):
281 class SVP64PredCR(Enum
):
293 class SVP64RMMode(Enum
):
300 PARALLEL
= 6 # Parallel Reduction
304 class SVP64BCPredMode(Enum
):
311 class SVP64BCVLSETMode(Enum
):
317 # note that these are chosen to be exactly the same as
318 # SVP64 RM bit 4. ALL=1 => bit4=1
320 class SVP64BCGate(Enum
):
325 class SVP64BCCTRMode(Enum
):
332 class SVP64width(Enum
):
340 class SVP64subvl(Enum
):
348 class SVP64sat(Enum
):
355 class SVP64LDSTmode(Enum
):
390 # supported instructions: make sure to keep up-to-date with CSV files
391 # just like everything else
393 "NONE", "add", "addc", "addco", "adde", "addeo",
394 "addi", "addic", "addic.", "addis",
395 "addme", "addmeo", "addo", "addze", "addzeo",
397 "and", "andc", "andi.", "andis.",
399 "absdu", "absds", # AV bitmanip
400 "absdacs", "absdacu", # AV bitmanip
401 "avgadd", # AV bitmanip
402 "b", "bc", "bcctr", "bclr", "bctar",
403 "bmask", # AV bitmanip
407 "cmp", "cmpb", "cmpeqb", "cmpi", "cmpl", "cmpli", "cmprb",
408 "cntlzd", "cntlzw", "cnttzd", "cnttzw",
409 "cprop", # AV bitmanip
410 "crand", "crandc", "creqv",
411 "crnand", "crnor", "cror", "crorc", "crxor",
413 "dcbf", "dcbst", "dcbt", "dcbtst", "dcbz",
414 "divd", "divde", "divdeo", "divdeu",
415 "divdeuo", "divdo", "divdu", "divduo", "divw", "divwe", "divweo",
416 "divweu", "divweuo", "divwo", "divwu", "divwuo",
418 "extsb", "extsh", "extsw", "extswsli",
419 "fadd", "fadds", "fsub", "fsubs", # FP add / sub
420 "fcfids", "fcfidus", "fsqrts", "fres", "frsqrtes", # FP stuff
421 "fdmadds", # DCT FP 3-arg
422 "fmsubs", "fmadds", "fnmsubs", "fnmadds", # FP 3-arg
423 "ffadds", "ffsubs", "ffmuls", "ffdivs", # FFT FP 2-arg
424 "ffmsubs", "ffmadds", "ffnmsubs", "ffnmadds", # FFT FP 3-arg
425 "fmul", "fmuls", "fdiv", "fdivs", # FP mul / div
426 "fmr", "fabs", "fnabs", "fneg", "fcpsgn", # FP move/abs/neg
427 "fsins", "fcoss", # FP SIN/COS
428 "fmvis", # FP load immediate
429 "fishmv", # Float Replace Lower-Half Single, Immediate
430 'grev', 'grev.', 'grevi', 'grevi.',
431 'grevw', 'grevw.', 'grevwi', 'grevwi.',
432 "hrfid", "icbi", "icbt", "isel", "isync",
433 "lbarx", "lbz", "lbzcix", "lbzu", "lbzux", "lbzx", # load byte
434 "ld", "ldarx", "ldbrx", "ldu", "ldux", "ldx", # load double
435 # "lbzbr", "lbzubr", # load byte SVP64 bit-reversed
436 # "ldbr", "ldubr", # load double SVP64 bit-reversed
437 "lfs", "lfsx", "lfsu", "lfsux", # FP load single
438 "lfd", "lfdx", "lfdu", "lfdux", "lfiwzx", "lfiwax", # FP load double
439 "lha", "lharx", "lhau", "lhaux", "lhax", # load half
440 "lhbrx", "lhz", "lhzu", "lhzux", "lhzx", # more load half
441 # "lhabr", "lhaubr", # load half SVP64 bit-reversed
442 # "lhzbr", "lhzubr", # more load half SVP64 bit-reversed
443 "lwa", "lwarx", "lwaux", "lwax", "lwbrx", # load word
444 "lwz", "lwzcix", "lwzu", "lwzux", "lwzx", # more load word
445 # "lwabr", # load word SVP64 bit-reversed
446 # "lwzbr", "lwzubr", # more load word SVP64 bit-reversed
447 "maddhd", "maddhdu", "maddld", # INT multiply-and-add
448 "mcrf", "mcrxr", "mcrxrx", "mfcr/mfocrf", # CR mvs
450 "mins", "maxs", "minu", "maxu", # AV bitmanip
451 "modsd", "modsw", "modud", "moduw",
452 "mtcrf/mtocrf", "mtmsr", "mtmsrd", "mtspr",
453 "mulhd", "mulhdu", "mulhw", "mulhwu", "mulld", "mulldo",
454 "mulli", "mullw", "mullwo",
455 "nand", "neg", "nego",
457 "nor", "or", "orc", "ori", "oris",
458 "popcntb", "popcntd", "popcntw",
461 "rldcl", "rldcr", "rldic", "rldicl", "rldicr", "rldimi",
462 "rlwimi", "rlwinm", "rlwnm",
464 "setvl", # https://libre-soc.org/openpower/sv/setvl
465 "svindex", # https://libre-soc.org/openpower/sv/remap
466 "svremap", # https://libre-soc.org/openpower/sv/remap - TEMPORARY
467 "svshape", # https://libre-soc.org/openpower/sv/remap/#svshape
468 "svshape2", # https://libre-soc.org/openpower/sv/remap/discussion TODO
469 "svstep", # https://libre-soc.org/openpower/sv/setvl
471 "slbia", "sld", "slw", "srad", "sradi",
472 "sraw", "srawi", "srd", "srw",
473 "stb", "stbcix", "stbcx", "stbu", "stbux", "stbx",
474 "std", "stdbrx", "stdcx", "stdu", "stdux", "stdx",
475 "stfs", "stfsx", "stfsu", "stfux", "stfsux", # FP store single
476 "stfd", "stfdx", "stfdu", "stfdux", "stfiwx", # FP store double
477 "sth", "sthbrx", "sthcx", "sthu", "sthux", "sthx",
478 "stw", "stwbrx", "stwcx", "stwu", "stwux", "stwx",
479 "subf", "subfc", "subfco", "subfe", "subfeo", "subfic",
480 "subfme", "subfmeo", "subfo", "subfze", "subfzeo",
484 "tlbie", "tlbiel", "tlbsync",
487 "xor", "xori", "xoris",
490 # two-way lookup of instruction-to-index and vice-versa
493 for i
, insn
in enumerate(_insns
):
497 # must be long enough to cover all instructions
498 asmlen
= len(_insns
).bit_length()
500 # Internal Operation numbering. Add new opcodes here (FPADD, FPMUL etc.)
505 OP_ILLEGAL
= 0 # important that this is zero (see power_decoder.py)
579 OP_FPOP
= 77 # temporary: replace with actual ops
580 OP_FPOP_I
= 78 # temporary: replace with actual ops
608 RS
= 4 # for some ALU/Logical operations
628 RS
= 13 # for shiftrot (M-Form)
630 CONST_SVD
= 15 # for SVD-Form
631 CONST_SVDS
= 16 # for SVDS-Form
639 RB
= 2 # for shiftrot (M-Form)
642 RC
= 5 # for SVP64 bit-reverse LD/ST
643 RT
= 6 # for ternlog[i]
665 # Backward compatibility
670 class LDSTMode(Enum
):
682 RC_ONLY
= 3 # does not include OE
706 class CROutSel(Enum
):
715 # SPRs - Special-Purpose Registers. See V3.0B Figure 18 p971 and
716 # http://libre-riscv.org/openpower/isatables/sprs.csv
717 # http://bugs.libre-riscv.org/show_bug.cgi?id=261
718 # http://bugs.libre-riscv.org/show_bug.cgi?id=859 - KAIVB
720 def get_spr_enum(full_file
):
721 """get_spr_enum - creates an Enum of SPRs, dynamically
722 has the option to reduce the enum to a much shorter list.
723 this saves drastically on the size of the regfile
725 short_list
= {'PIDR', 'DAR', 'PRTBL', 'DSISR', 'SVSRR0', 'SVSTATE',
726 'SVSTATE0', 'SVSTATE1', 'SVSTATE2', 'SVSTATE3',
727 'SPRG0_priv', 'SPRG1_priv', 'SPRG2_priv', 'SPRG3_priv',
728 'SPRG0', 'SPRG1', 'SPRG2', 'SPRG3', 'KAIVB',
729 # hmmm should not be including these, they are FAST regs
730 'CTR', 'LR', 'TAR', 'SRR0', 'SRR1', 'XER', 'DEC', 'TB', 'TBU',
731 'HSRR0', 'HSRR1', 'HSPRG0', 'HSPRG1',
734 for row
in get_csv("sprs.csv"):
735 if full_file
or row
['SPR'] in short_list
:
738 spr_info
= namedtuple('spr_info', 'SPR priv_mtspr priv_mfspr length idx')
742 info
= spr_info(SPR
=row
['SPR'], priv_mtspr
=row
['priv_mtspr'],
743 priv_mfspr
=row
['priv_mfspr'], length
=int(row
['len']),
745 spr_dict
[int(row
['Idx'])] = info
746 spr_byname
[row
['SPR']] = info
747 fields
= [(row
['SPR'], int(row
['Idx'])) for row
in spr_csv
]
748 SPR
= Enum('SPR', fields
)
749 return SPR
, spr_dict
, spr_byname
752 SPRfull
, spr_dict
, spr_byname
= get_spr_enum(full_file
=True)
753 SPRreduced
, _
, _
= get_spr_enum(full_file
=False)
763 MSRSpec
= namedtuple("MSRSpec", ["dr", "pr", "sf"])
765 if __name__
== '__main__':
766 # find out what the heck is in SPR enum :)
767 print("sprs full", len(SPRfull
))
769 print("sprs reduced", len(SPRreduced
))
770 print(dir(SPRreduced
))
772 print(SPRfull
.__members
__['TAR'])
774 print("full", x
, x
.value
, str(x
), x
.name
)
776 print("reduced", x
, x
.value
, str(x
), x
.name
)
778 print("function", Function
.ALU
.name
)