46e97d6964aaa0a7fb5e91964036126cc336b441
[soc.git] / src / soc / decoder / power_enums.py
1 # SPDX-License: LGPLv3+
2 # Copyright (C) 2020, 2021 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
3 # Copyright (C) 2020, Michael Nolan
4
5 from enum import Enum, unique
6 import csv
7 import os
8 from os.path import dirname, join
9 from collections import namedtuple
10
11
12 def find_wiki_dir():
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')
18
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')
25
26 return join(find_wiki_dir(), name)
27
28
29 def get_csv(name):
30 file_path = find_wiki_file(name)
31 with open(file_path, 'r') as csvfile:
32 reader = csv.DictReader(csvfile)
33 return list(reader)
34
35
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']
40
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',
44 'CR in': 'NONE',
45 'ldst len': 'NONE',
46 'upd': '0',
47 'rc': 'NONE', 'cry in': 'ZERO', 'form': 'NONE'}
48
49
50 def get_signal_name(name):
51 if name[0].isdigit():
52 name = "is_" + name
53 return name.lower().replace(' ', '_')
54
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.)
58 @unique
59 class Function(Enum):
60 NONE = 0
61 ALU = 1 << 1
62 LDST = 1 << 2
63 SHIFT_ROT = 1 << 3
64 LOGICAL = 1 << 4
65 BRANCH = 1 << 5
66 CR = 1 << 6
67 TRAP = 1 << 7
68 MUL = 1 << 8
69 DIV = 1 << 9
70 SPR = 1 << 10
71 MMU = 1 << 11
72 SV = 1 << 12 # Simple-V https://libre-soc.org/openpower/sv
73
74
75 @unique
76 class Form(Enum):
77 NONE = 0
78 I = 1
79 B = 2
80 SC = 3
81 D = 4
82 DS = 5
83 DQ = 6
84 DX = 7
85 X = 8
86 XL = 9
87 XFX = 10
88 XFL = 11
89 XX1 = 12
90 XX2 = 13
91 XX3 = 14
92 XX4 = 15
93 XS = 16
94 XO = 17
95 A = 18
96 M = 19
97 MD = 20
98 MDS = 21
99 VA = 22
100 VC = 23
101 VX = 24
102 EVX = 25
103 EVS = 26
104 Z22 = 27
105 Z23 = 28
106
107 # Simple-V svp64 fields https://libre-soc.org/openpower/sv/svp64/
108
109 @unique
110 class SVPtype(Enum):
111 NONE = 0
112 P1 = 1
113 P2 = 2
114
115 @unique
116 class SVEtype(Enum):
117 NONE = 0
118 EXTRA2 = 1
119 EXTRA3 = 2
120
121 @unique
122 class SVEXTRA(Enum):
123 NONE = 0
124 Idx0 = 1
125 Idx1 = 2
126 Idx2 = 3
127 Idx3 = 4
128 Idx_1_2 = 5 # due to weird BA/BB for crops
129
130 # supported instructions: make sure to keep up-to-date with CSV files
131 # just like everything else
132 _insns = [
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",
153 "rlwnm", "setb",
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",
162 ]
163
164 # two-way lookup of instruction-to-index and vice-versa
165 insns = {}
166 asmidx = {}
167 for i, insn in enumerate(_insns):
168 insns[i] = insn
169 asmidx[insn] = i
170
171 # Internal Operation numbering. Add new opcodes here (FPADD, FPMUL etc.)
172 @unique
173 class MicrOp(Enum):
174 OP_ILLEGAL = 0 # important that this is zero (see power_decoder.py)
175 OP_NOP = 1
176 OP_ADD = 2
177 OP_ADDPCIS = 3
178 OP_AND = 4
179 OP_ATTN = 5
180 OP_B = 6
181 OP_BC = 7
182 OP_BCREG = 8
183 OP_BPERM = 9
184 OP_CMP = 10
185 OP_CMPB = 11
186 OP_CMPEQB = 12
187 OP_CMPRB = 13
188 OP_CNTZ = 14
189 OP_CRAND = 15
190 OP_CRANDC = 16
191 OP_CREQV = 17
192 OP_CRNAND = 18
193 OP_CRNOR = 19
194 OP_CROR = 20
195 OP_CRORC = 21
196 OP_CRXOR = 22
197 OP_DARN = 23
198 OP_DCBF = 24
199 OP_DCBST = 25
200 OP_DCBT = 26
201 OP_DCBTST = 27
202 OP_DCBZ = 28
203 OP_DIV = 29
204 OP_DIVE = 30
205 OP_EXTS = 31
206 OP_EXTSWSLI = 32
207 OP_ICBI = 33
208 OP_ICBT = 34
209 OP_ISEL = 35
210 OP_ISYNC = 36
211 OP_LOAD = 37
212 OP_STORE = 38
213 OP_MADDHD = 39
214 OP_MADDHDU = 40
215 OP_MADDLD = 41
216 OP_MCRF = 42
217 OP_MCRXR = 43
218 OP_MCRXRX = 44
219 OP_MFCR = 45
220 OP_MFSPR = 46
221 OP_MOD = 47
222 OP_MTCRF = 48
223 OP_MTSPR = 49
224 OP_MUL_L64 = 50
225 OP_MUL_H64 = 51
226 OP_MUL_H32 = 52
227 OP_OR = 53
228 OP_POPCNT = 54
229 OP_PRTY = 55
230 OP_RLC = 56
231 OP_RLCL = 57
232 OP_RLCR = 58
233 OP_SETB = 59
234 OP_SHL = 60
235 OP_SHR = 61
236 OP_SYNC = 62
237 OP_TRAP = 63
238 OP_XOR = 67
239 OP_SIM_CONFIG = 68
240 OP_CROP = 69
241 OP_RFID = 70
242 OP_MFMSR = 71
243 OP_MTMSRD = 72
244 OP_SC = 73
245 OP_MTMSR = 74
246 OP_TLBIE = 75
247
248
249 @unique
250 class In1Sel(Enum):
251 NONE = 0
252 RA = 1
253 RA_OR_ZERO = 2
254 SPR = 3
255 RS = 4 # for some ALU/Logical operations
256
257
258 @unique
259 class In2Sel(Enum):
260 NONE = 0
261 RB = 1
262 CONST_UI = 2
263 CONST_SI = 3
264 CONST_UI_HI = 4
265 CONST_SI_HI = 5
266 CONST_LI = 6
267 CONST_BD = 7
268 CONST_DS = 8
269 CONST_M1 = 9
270 CONST_SH = 10
271 CONST_SH32 = 11
272 SPR = 12
273 RS = 13 # for shiftrot (M-Form)
274
275
276 @unique
277 class In3Sel(Enum):
278 NONE = 0
279 RS = 1
280 RB = 2 # for shiftrot (M-Form)
281
282
283 @unique
284 class OutSel(Enum):
285 NONE = 0
286 RT = 1
287 RA = 2
288 SPR = 3
289
290
291 @unique
292 class LdstLen(Enum):
293 NONE = 0
294 is1B = 1
295 is2B = 2
296 is4B = 4
297 is8B = 8
298
299
300 @unique
301 class LDSTMode(Enum):
302 NONE = 0
303 update = 1
304 cix = 2
305 cx = 3
306
307
308 @unique
309 class RC(Enum):
310 NONE = 0
311 ONE = 1
312 RC = 2
313
314
315 @unique
316 class CryIn(Enum):
317 ZERO = 0
318 ONE = 1
319 CA = 2
320 # TODO OV = 3
321
322
323 @unique
324 class CRInSel(Enum):
325 NONE = 0
326 CR0 = 1
327 BI = 2
328 BFA = 3
329 BA_BB = 4
330 BC = 5
331 WHOLE_REG = 6
332 CR1 = 7
333
334
335 @unique
336 class CROutSel(Enum):
337 NONE = 0
338 CR0 = 1
339 BF = 2
340 BT = 3
341 WHOLE_REG = 4
342 CR1 = 5
343
344
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
348
349 spr_csv = get_csv("sprs.csv")
350 spr_info = namedtuple('spr_info', 'SPR priv_mtspr priv_mfspr length idx')
351 spr_dict = {}
352 spr_byname = {}
353 for row in spr_csv:
354 info = spr_info(SPR=row['SPR'], priv_mtspr=row['priv_mtspr'],
355 priv_mfspr=row['priv_mfspr'], length=int(row['len']),
356 idx=int(row['Idx']))
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)
361
362
363 XER_bits = {
364 'SO': 32,
365 'OV': 33,
366 'CA': 34,
367 'OV32': 44,
368 'CA32': 45
369 }
370
371 if __name__ == '__main__':
372 # find out what the heck is in SPR enum :)
373 print("sprs", len(SPR))
374 print(dir(SPR))
375 print(dir(Enum))
376 print(SPR.__members__['TAR'])
377 for x in SPR:
378 print(x, x.value, str(x), x.name)
379
380 print ("function", Function.ALU.name)