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