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