1 # SPDX-License: LGPLv3+
2 # Copyright (C) 2020, 2021 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
3 # Copyright (C) 2020, Michael Nolan
5 from enum
import Enum
, unique
8 from os
.path
import dirname
, join
9 from collections
import namedtuple
13 filedir
= os
.path
.dirname(os
.path
.abspath(__file__
))
14 basedir
= dirname(dirname(dirname(filedir
)))
15 tabledir
= join(basedir
, 'libreriscv')
16 tabledir
= join(tabledir
, 'openpower')
17 return join(tabledir
, 'isatables')
19 def find_wiki_file(name
):
20 filedir
= os
.path
.dirname(os
.path
.abspath(__file__
))
21 basedir
= dirname(dirname(dirname(filedir
)))
22 tabledir
= join(basedir
, 'libreriscv')
23 tabledir
= join(tabledir
, 'openpower')
24 tabledir
= join(tabledir
, 'isatables')
26 return join(find_wiki_dir(), name
)
30 file_path
= find_wiki_file(name
)
31 with
open(file_path
, 'r') as csvfile
:
32 reader
= csv
.DictReader(csvfile
)
36 # names of the fields in the tables that don't correspond to an enum
37 single_bit_flags
= ['inv A', 'inv out',
38 'cry out', 'BR', 'sgn ext', 'rsrv', '32b',
39 'sgn', 'lk', 'sgl pipe']
41 # default values for fields in the table
42 default_values
= {'unit': "NONE", 'internal op': "OP_ILLEGAL",
43 'in1': "RA", 'in2': 'NONE', 'in3': 'NONE', 'out': 'NONE',
47 'rc': 'NONE', 'cry in': 'ZERO', 'form': 'NONE'}
50 def get_signal_name(name
):
53 return name
.lower().replace(' ', '_')
55 # this corresponds to which Function Unit (pipeline-with-Reservation-Stations)
56 # is to process and guard the operation. they are roughly divided by having
57 # the same register input/output signature (X-Form, etc.)
72 SV
= 1 << 12 # Simple-V https://libre-soc.org/openpower/sv
107 # Simple-V svp64 fields https://libre-soc.org/openpower/sv/svp64/
128 Idx_1_2
= 5 # due to weird BA/BB for crops
130 # supported instructions: make sure to keep up-to-date with CSV files
131 # just like everything else
133 "NONE", "add", "addc", "addco", "adde", "addeo", "addi", "addic", "addic.",
134 "addis", "addme", "addmeo", "addo", "addze", "addzeo", "and", "andc",
135 "andi.", "andis.", "attn", "b", "bc", "bcctr", "bclr", "bctar",
136 "bpermd", "cmp", "cmpb", "cmpeqb", "cmpi", "cmpl", "cmpli", "cmprb",
137 "cntlzd", "cntlzw", "cnttzd", "cnttzw", "crand", "crandc", "creqv",
138 "crnand", "crnor", "cror", "crorc", "crxor", "darn", "dcbf", "dcbst",
139 "dcbt", "dcbtst", "dcbz", "divd", "divde", "divdeo", "divdeu",
140 "divdeuo", "divdo", "divdu", "divduo", "divw", "divwe", "divweo",
141 "divweu", "divweuo", "divwo", "divwu", "divwuo", "eqv", "extsb",
142 "extsh", "extsw", "extswsli", "hrfid", "icbi", "icbt", "isel", "isync",
143 "lbarx", "lbz", "lbzu", "lbzux", "lbzx", "ld", "ldarx", "ldbrx",
144 "ldu", "ldux", "ldx", "lha", "lharx", "lhau", "lhaux", "lhax",
145 "lhbrx", "lhz", "lhzu", "lhzux", "lhzx", "lwa", "lwarx", "lwaux",
146 "lwax", "lwbrx", "lwz", "lwzcix", "lwzu", "lwzux", "lwzx", "mcrf", "mcrxr",
147 "mcrxrx", "mfcr/mfocrf", "mfmsr", "mfspr", "modsd", "modsw", "modud",
148 "moduw", "mtcrf/mtocrf", "mtmsr", "mtmsrd", "mtspr", "mulhd", "mulhdu",
149 "mulhw", "mulhwu", "mulld", "mulldo", "mulli", "mullw", "mullwo",
150 "nand", "neg", "nego", "nop", "nor", "or", "orc", "ori", "oris",
151 "popcntb", "popcntd", "popcntw", "prtyd", "prtyw", "rfid", "rldcl",
152 "rldcr", "rldic", "rldicl", "rldicr", "rldimi", "rlwimi", "rlwinm",
154 "setvl", # https://libre-soc.org/openpower/sv/setvl
155 "sim_cfg", "slbia", "sld", "slw", "srad", "sradi", "sraw",
156 "srawi", "srd", "srw", "stb", "stbcix", "stbcx", "stbu", "stbux", "stbx",
157 "std", "stdbrx", "stdcx", "stdu", "stdux", "stdx", "sth", "sthbrx", "sthcx",
158 "sthu", "sthux", "sthx", "stw", "stwbrx", "stwcx", "stwu", "stwux",
159 "stwx", "subf", "subfc", "subfco", "subfe", "subfeo", "subfic",
160 "subfme", "subfmeo", "subfo", "subfze", "subfzeo", "sync", "td",
161 "tdi", "tlbie", "tlbiel", "tw", "twi", "xor", "xori", "xoris",
164 # two-way lookup of instruction-to-index and vice-versa
167 for i
, insn
in enumerate(_insns
):
171 # Internal Operation numbering. Add new opcodes here (FPADD, FPMUL etc.)
174 OP_ILLEGAL
= 0 # important that this is zero (see power_decoder.py)
255 RS
= 4 # for some ALU/Logical operations
273 RS
= 13 # for shiftrot (M-Form)
280 RB
= 2 # for shiftrot (M-Form)
301 class LDSTMode(Enum
):
336 class CROutSel(Enum
):
345 # SPRs - Special-Purpose Registers. See V3.0B Figure 18 p971 and
346 # http://libre-riscv.org/openpower/isatables/sprs.csv
347 # http://bugs.libre-riscv.org/show_bug.cgi?id=261
349 spr_csv
= get_csv("sprs.csv")
350 spr_info
= namedtuple('spr_info', 'SPR priv_mtspr priv_mfspr length idx')
354 info
= spr_info(SPR
=row
['SPR'], priv_mtspr
=row
['priv_mtspr'],
355 priv_mfspr
=row
['priv_mfspr'], length
=int(row
['len']),
357 spr_dict
[int(row
['Idx'])] = info
358 spr_byname
[row
['SPR']] = info
359 fields
= [(row
['SPR'], int(row
['Idx'])) for row
in spr_csv
]
360 SPR
= Enum('SPR', fields
)
371 if __name__
== '__main__':
372 # find out what the heck is in SPR enum :)
373 print("sprs", len(SPR
))
376 print(SPR
.__members
__['TAR'])
378 print(x
, x
.value
, str(x
), x
.name
)
380 print ("function", Function
.ALU
.name
)