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