more fixes for radixmmu.py
[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 """Enums used in OpenPOWER ISA decoding
6
7 Note: for SV, from v3.1B p12:
8
9 The designated SPR sandbox consists of non-privileged SPRs 704-719 and
10 privileged SPRs 720-735.
11
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
14 get_spr_enum
15 """
16
17 from enum import Enum, unique
18 import csv
19 import os
20 from os.path import dirname, join
21 from collections import namedtuple
22
23
24 def find_wiki_dir():
25 filedir = os.path.dirname(os.path.abspath(__file__))
26 basedir = dirname(dirname(dirname(filedir)))
27 tabledir = join(basedir, 'libreriscv')
28 tabledir = join(tabledir, 'openpower')
29 return join(tabledir, 'isatables')
30
31
32 def find_wiki_file(name):
33 filedir = os.path.dirname(os.path.abspath(__file__))
34 basedir = dirname(dirname(dirname(filedir)))
35 tabledir = join(basedir, 'libreriscv')
36 tabledir = join(tabledir, 'openpower')
37 tabledir = join(tabledir, 'isatables')
38
39 return join(find_wiki_dir(), name)
40
41
42 def get_csv(name):
43 file_path = find_wiki_file(name)
44 with open(file_path, 'r') as csvfile:
45 reader = csv.DictReader(csvfile)
46 return list(reader)
47
48
49 # names of the fields in the tables that don't correspond to an enum
50 single_bit_flags = ['inv A', 'inv out',
51 'cry out', 'BR', 'sgn ext', 'rsrv', '32b',
52 'sgn', 'lk', 'sgl pipe']
53
54 # default values for fields in the table
55 default_values = {'unit': "NONE", 'internal op': "OP_ILLEGAL",
56 'in1': "RA", 'in2': 'NONE', 'in3': 'NONE', 'out': 'NONE',
57 'CR in': 'NONE',
58 'ldst len': 'NONE',
59 'upd': '0',
60 'rc': 'NONE', 'cry in': 'ZERO', 'form': 'NONE'}
61
62
63 def get_signal_name(name):
64 if name[0].isdigit():
65 name = "is_" + name
66 return name.lower().replace(' ', '_')
67
68 # this corresponds to which Function Unit (pipeline-with-Reservation-Stations)
69 # is to process and guard the operation. they are roughly divided by having
70 # the same register input/output signature (X-Form, etc.)
71
72
73 @unique
74 class Function(Enum):
75 NONE = 0
76 ALU = 1 << 1
77 LDST = 1 << 2
78 SHIFT_ROT = 1 << 3
79 LOGICAL = 1 << 4
80 BRANCH = 1 << 5
81 CR = 1 << 6
82 TRAP = 1 << 7
83 MUL = 1 << 8
84 DIV = 1 << 9
85 SPR = 1 << 10
86 MMU = 1 << 11
87 SV = 1 << 12 # Simple-V https://libre-soc.org/openpower/sv
88 VL = 1 << 13 # setvl
89
90
91 @unique
92 class Form(Enum):
93 NONE = 0
94 I = 1
95 B = 2
96 SC = 3
97 D = 4
98 DS = 5
99 DQ = 6
100 DX = 7
101 X = 8
102 XL = 9
103 XFX = 10
104 XFL = 11
105 XX1 = 12
106 XX2 = 13
107 XX3 = 14
108 XX4 = 15
109 XS = 16
110 XO = 17
111 A = 18
112 M = 19
113 MD = 20
114 MDS = 21
115 VA = 22
116 VC = 23
117 VX = 24
118 EVX = 25
119 EVS = 26
120 Z22 = 27
121 Z23 = 28
122 SVL = 29 # Simple-V for setvl instruction
123
124 # Simple-V svp64 fields https://libre-soc.org/openpower/sv/svp64/
125
126
127 @unique
128 class SVPtype(Enum):
129 NONE = 0
130 P1 = 1
131 P2 = 2
132
133
134 @unique
135 class SVEtype(Enum):
136 NONE = 0
137 EXTRA2 = 1
138 EXTRA3 = 2
139
140
141 @unique
142 class SVEXTRA(Enum):
143 NONE = 0
144 Idx0 = 1
145 Idx1 = 2
146 Idx2 = 3
147 Idx3 = 4
148 Idx_1_2 = 5 # due to weird BA/BB for crops
149
150
151 @unique
152 class SVP64PredMode(Enum):
153 ALWAYS = 0
154 INT = 1
155 CR = 2
156
157
158 @unique
159 class SVP64PredInt(Enum):
160 ALWAYS = 0
161 R3_UNARY = 1
162 R3 = 2
163 R3_N = 3
164 R10 = 4
165 R10_N = 5
166 R30 = 6
167 R30_N = 7
168
169
170 @unique
171 class SVP64PredCR(Enum):
172 LT = 0
173 GE = 1
174 GT = 2
175 LE = 3
176 EQ = 4
177 NE = 5
178 SO = 6
179 NS = 7
180
181
182 @unique
183 class SVP64RMMode(Enum):
184 NORMAL = 0
185 MAPREDUCE = 1
186 FFIRST = 2
187 SATURATE = 3
188 PREDRES = 4
189
190
191 @unique
192 class SVP64width(Enum):
193 DEFAULT = 0
194 EW_32 = 1
195 EW_16 = 2
196 EW_8 = 3
197
198
199 @unique
200 class SVP64subvl(Enum):
201 VEC1 = 0
202 VEC2 = 1
203 VEC3 = 2
204 VEC4 = 3
205
206
207 @unique
208 class SVP64sat(Enum):
209 NONE = 0
210 SIGNED = 1
211 UNSIGNED = 2
212
213
214 # supported instructions: make sure to keep up-to-date with CSV files
215 # just like everything else
216 _insns = [
217 "NONE", "add", "addc", "addco", "adde", "addeo", "addi", "addic", "addic.",
218 "addis", "addme", "addmeo", "addo", "addze", "addzeo", "and", "andc",
219 "andi.", "andis.", "attn", "b", "bc", "bcctr", "bclr", "bctar",
220 "bpermd", "cmp", "cmpb", "cmpeqb", "cmpi", "cmpl", "cmpli", "cmprb",
221 "cntlzd", "cntlzw", "cnttzd", "cnttzw", "crand", "crandc", "creqv",
222 "crnand", "crnor", "cror", "crorc", "crxor", "darn", "dcbf", "dcbst",
223 "dcbt", "dcbtst", "dcbz", "divd", "divde", "divdeo", "divdeu",
224 "divdeuo", "divdo", "divdu", "divduo", "divw", "divwe", "divweo",
225 "divweu", "divweuo", "divwo", "divwu", "divwuo", "eqv", "extsb",
226 "extsh", "extsw", "extswsli", "hrfid", "icbi", "icbt", "isel", "isync",
227 "lbarx", "lbz", "lbzu", "lbzux", "lbzx", "ld", "ldarx", "ldbrx",
228 "ldu", "ldux", "ldx", "lha", "lharx", "lhau", "lhaux", "lhax",
229 "lhbrx", "lhz", "lhzu", "lhzux", "lhzx", "lwa", "lwarx", "lwaux",
230 "lwax", "lwbrx", "lwz", "lwzcix", "lwzu", "lwzux", "lwzx", "mcrf", "mcrxr",
231 "mcrxrx", "mfcr/mfocrf", "mfmsr", "mfspr", "modsd", "modsw", "modud",
232 "moduw", "mtcrf/mtocrf", "mtmsr", "mtmsrd", "mtspr", "mulhd", "mulhdu",
233 "mulhw", "mulhwu", "mulld", "mulldo", "mulli", "mullw", "mullwo",
234 "nand", "neg", "nego", "nop", "nor", "or", "orc", "ori", "oris",
235 "popcntb", "popcntd", "popcntw", "prtyd", "prtyw", "rfid", "rldcl",
236 "rldcr", "rldic", "rldicl", "rldicr", "rldimi", "rlwimi", "rlwinm",
237 "rlwnm", "setb",
238 "setvl", # https://libre-soc.org/openpower/sv/setvl
239 "sim_cfg", "slbia", "sld", "slw", "srad", "sradi", "sraw",
240 "srawi", "srd", "srw", "stb", "stbcix", "stbcx", "stbu", "stbux", "stbx",
241 "std", "stdbrx", "stdcx", "stdu", "stdux", "stdx", "sth", "sthbrx", "sthcx",
242 "sthu", "sthux", "sthx", "stw", "stwbrx", "stwcx", "stwu", "stwux",
243 "stwx", "subf", "subfc", "subfco", "subfe", "subfeo", "subfic",
244 "subfme", "subfmeo", "subfo", "subfze", "subfzeo", "sync", "td",
245 "tdi", "tlbie", "tlbiel", "tw", "twi", "xor", "xori", "xoris",
246 ]
247
248 # two-way lookup of instruction-to-index and vice-versa
249 insns = {}
250 asmidx = {}
251 for i, insn in enumerate(_insns):
252 insns[i] = insn
253 asmidx[insn] = i
254
255 # Internal Operation numbering. Add new opcodes here (FPADD, FPMUL etc.)
256
257
258 @unique
259 class MicrOp(Enum):
260 OP_ILLEGAL = 0 # important that this is zero (see power_decoder.py)
261 OP_NOP = 1
262 OP_ADD = 2
263 OP_ADDPCIS = 3
264 OP_AND = 4
265 OP_ATTN = 5
266 OP_B = 6
267 OP_BC = 7
268 OP_BCREG = 8
269 OP_BPERM = 9
270 OP_CMP = 10
271 OP_CMPB = 11
272 OP_CMPEQB = 12
273 OP_CMPRB = 13
274 OP_CNTZ = 14
275 OP_CRAND = 15
276 OP_CRANDC = 16
277 OP_CREQV = 17
278 OP_CRNAND = 18
279 OP_CRNOR = 19
280 OP_CROR = 20
281 OP_CRORC = 21
282 OP_CRXOR = 22
283 OP_DARN = 23
284 OP_DCBF = 24
285 OP_DCBST = 25
286 OP_DCBT = 26
287 OP_DCBTST = 27
288 OP_DCBZ = 28
289 OP_DIV = 29
290 OP_DIVE = 30
291 OP_EXTS = 31
292 OP_EXTSWSLI = 32
293 OP_ICBI = 33
294 OP_ICBT = 34
295 OP_ISEL = 35
296 OP_ISYNC = 36
297 OP_LOAD = 37
298 OP_STORE = 38
299 OP_MADDHD = 39
300 OP_MADDHDU = 40
301 OP_MADDLD = 41
302 OP_MCRF = 42
303 OP_MCRXR = 43
304 OP_MCRXRX = 44
305 OP_MFCR = 45
306 OP_MFSPR = 46
307 OP_MOD = 47
308 OP_MTCRF = 48
309 OP_MTSPR = 49
310 OP_MUL_L64 = 50
311 OP_MUL_H64 = 51
312 OP_MUL_H32 = 52
313 OP_OR = 53
314 OP_POPCNT = 54
315 OP_PRTY = 55
316 OP_RLC = 56
317 OP_RLCL = 57
318 OP_RLCR = 58
319 OP_SETB = 59
320 OP_SHL = 60
321 OP_SHR = 61
322 OP_SYNC = 62
323 OP_TRAP = 63
324 OP_XOR = 67
325 OP_SIM_CONFIG = 68
326 OP_CROP = 69
327 OP_RFID = 70
328 OP_MFMSR = 71
329 OP_MTMSRD = 72
330 OP_SC = 73
331 OP_MTMSR = 74
332 OP_TLBIE = 75
333 OP_SETVL = 76
334
335
336 @unique
337 class In1Sel(Enum):
338 NONE = 0
339 RA = 1
340 RA_OR_ZERO = 2
341 SPR = 3
342 RS = 4 # for some ALU/Logical operations
343
344
345 @unique
346 class In2Sel(Enum):
347 NONE = 0
348 RB = 1
349 CONST_UI = 2
350 CONST_SI = 3
351 CONST_UI_HI = 4
352 CONST_SI_HI = 5
353 CONST_LI = 6
354 CONST_BD = 7
355 CONST_DS = 8
356 CONST_M1 = 9
357 CONST_SH = 10
358 CONST_SH32 = 11
359 SPR = 12
360 RS = 13 # for shiftrot (M-Form)
361
362
363 @unique
364 class In3Sel(Enum):
365 NONE = 0
366 RS = 1
367 RB = 2 # for shiftrot (M-Form)
368
369
370 @unique
371 class OutSel(Enum):
372 NONE = 0
373 RT = 1
374 RA = 2
375 SPR = 3
376 RT_OR_ZERO = 4
377
378
379 @unique
380 class LdstLen(Enum):
381 NONE = 0
382 is1B = 1
383 is2B = 2
384 is4B = 4
385 is8B = 8
386
387
388 @unique
389 class LDSTMode(Enum):
390 NONE = 0
391 update = 1
392 cix = 2
393 cx = 3
394
395
396 @unique
397 class RC(Enum):
398 NONE = 0
399 ONE = 1
400 RC = 2
401
402
403 @unique
404 class CryIn(Enum):
405 ZERO = 0
406 ONE = 1
407 CA = 2
408 # TODO OV = 3
409
410
411 @unique
412 class CRInSel(Enum):
413 NONE = 0
414 CR0 = 1
415 BI = 2
416 BFA = 3
417 BA_BB = 4
418 BC = 5
419 WHOLE_REG = 6
420 CR1 = 7
421
422
423 @unique
424 class CROutSel(Enum):
425 NONE = 0
426 CR0 = 1
427 BF = 2
428 BT = 3
429 WHOLE_REG = 4
430 CR1 = 5
431
432
433 # SPRs - Special-Purpose Registers. See V3.0B Figure 18 p971 and
434 # http://libre-riscv.org/openpower/isatables/sprs.csv
435 # http://bugs.libre-riscv.org/show_bug.cgi?id=261
436
437 def get_spr_enum(full_file):
438 """get_spr_enum - creates an Enum of SPRs, dynamically
439 has the option to reduce the enum to a much shorter list.
440 this saves drastically on the size of the regfile
441 """
442 short_list = {'PIDR', 'DAR', 'PRTBL', 'DSISR', 'SVSRR0', 'SVSTATE',
443 'SPRG0_priv', 'SPRG1_priv', 'SPRG2_priv', 'SPRG3_priv',
444 'SPRG3'
445 }
446 spr_csv = []
447 for row in get_csv("sprs.csv"):
448 if full_file or row['SPR'] in short_list:
449 spr_csv.append(row)
450
451 spr_info = namedtuple('spr_info', 'SPR priv_mtspr priv_mfspr length idx')
452 spr_dict = {}
453 spr_byname = {}
454 for row in spr_csv:
455 info = spr_info(SPR=row['SPR'], priv_mtspr=row['priv_mtspr'],
456 priv_mfspr=row['priv_mfspr'], length=int(row['len']),
457 idx=int(row['Idx']))
458 spr_dict[int(row['Idx'])] = info
459 spr_byname[row['SPR']] = info
460 fields = [(row['SPR'], int(row['Idx'])) for row in spr_csv]
461 SPR = Enum('SPR', fields)
462 return SPR, spr_dict, spr_byname
463
464 SPRfull, spr_dict, spr_byname = get_spr_enum(full_file=True)
465 SPRreduced, _, _ = get_spr_enum(full_file=False)
466
467 XER_bits = {
468 'SO': 32,
469 'OV': 33,
470 'CA': 34,
471 'OV32': 44,
472 'CA32': 45
473 }
474
475 if __name__ == '__main__':
476 # find out what the heck is in SPR enum :)
477 print("sprs full", len(SPRfull))
478 print(dir(SPRfull))
479 print("sprs reduced", len(SPRreduced))
480 print(dir(SPRreduced))
481 print(dir(Enum))
482 print(SPRfull.__members__['TAR'])
483 for x in SPRfull:
484 print(x, x.value, str(x), x.name)
485
486 print("function", Function.ALU.name)