pywriter, pyfnwriter, parser: activate helper class
[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 SVD = 30 # Simple-V for LD/ST bit-reverse, variant of D-Form
120 SVDS = 31 # Simple-V for LD/ST bit-reverse, variant of DS-Form
121 SVM = 32 # Simple-V SHAPE mode - TEMPORARY TEMPORARY TEMPORARY
122 SVRM = 33 # Simple-V REMAP mode - TEMPORARY TEMPORARY TEMPORARY
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 BRANCH = 5
190
191
192 @unique
193 class SVP64BCPredMode(Enum):
194 NONE = 0
195 MASKZERO = 1
196 MASKONE = 2
197
198 @unique
199 class SVP64BCVLSETMode(Enum):
200 NONE = 0
201 VL_INCL = 1
202 VL_EXCL = 2
203
204
205 # note that these are chosen to be exactly the same as
206 # SVP64 RM bit 4. ALL=1 => bit4=1
207 @unique
208 class SVP64BCGate(Enum):
209 ANY = 0
210 ALL = 1
211
212
213 class SVP64BCCTRMode(Enum):
214 NONE = 0
215 TEST = 1
216 TEST_INV = 2
217
218
219 @unique
220 class SVP64width(Enum):
221 DEFAULT = 0
222 EW_32 = 1
223 EW_16 = 2
224 EW_8 = 3
225
226
227 @unique
228 class SVP64subvl(Enum):
229 VEC1 = 0
230 VEC2 = 1
231 VEC3 = 2
232 VEC4 = 3
233
234
235 @unique
236 class SVP64sat(Enum):
237 NONE = 0
238 SIGNED = 1
239 UNSIGNED = 2
240
241 @unique
242 class SVP64LDSTmode(Enum):
243 NONE = 0
244 INDEXED = 1
245 ELSTRIDE = 2
246 UNITSTRIDE = 3
247 SHIFT = 4
248
249
250 # supported instructions: make sure to keep up-to-date with CSV files
251 # just like everything else
252 _insns = [
253 "NONE", "add", "addc", "addco", "adde", "addeo",
254 "addi", "addic", "addic.", "addis",
255 "addme", "addmeo", "addo", "addze", "addzeo",
256 "addg6s",
257 "and", "andc", "andi.", "andis.",
258 "attn",
259 "b", "bc", "bcctr", "bclr", "bctar",
260 "bpermd",
261 "cbcdtd",
262 "cdtbcd",
263 "cmp", "cmpb", "cmpeqb", "cmpi", "cmpl", "cmpli", "cmprb",
264 "cntlzd", "cntlzw", "cnttzd", "cnttzw",
265 "crand", "crandc", "creqv",
266 "crnand", "crnor", "cror", "crorc", "crxor",
267 "darn",
268 "dcbf", "dcbst", "dcbt", "dcbtst", "dcbz",
269 "divd", "divde", "divdeo", "divdeu",
270 "divdeuo", "divdo", "divdu", "divduo", "divw", "divwe", "divweo",
271 "divweu", "divweuo", "divwo", "divwu", "divwuo",
272 "eqv",
273 "extsb", "extsh", "extsw", "extswsli",
274 "fadd", "fadds", "fsub", "fsubs", # FP add / sub
275 "fcfids", "fcfidus", "fsqrts", "fres", "frsqrtes", # FP stuff
276 "fdmadds", # DCT FP 3-arg
277 "fmsubs", "fmadds", "fnmsubs", "fnmadds", # FP 3-arg
278 "ffadds", "ffsubs", "ffmuls", "ffdivs", # FFT FP 2-arg
279 "ffmsubs", "ffmadds", "ffnmsubs", "ffnmadds", # FFT FP 3-arg
280 "fmul", "fmuls", "fdiv", "fdivs", # FP mul / div
281 "fmr", "fabs", "fnabs", "fneg", "fcpsgn", # FP move/abs/neg
282 "fsins", "fcoss", # FP SIN/COS
283 "hrfid", "icbi", "icbt", "isel", "isync",
284 "lbarx", "lbz", "lbzu", "lbzux", "lbzx", # load byte
285 "ld", "ldarx", "ldbrx", "ldu", "ldux", "ldx", # load double
286 #"lbzbr", "lbzubr", # load byte SVP64 bit-reversed
287 #"ldbr", "ldubr", # load double SVP64 bit-reversed
288 "lfs", "lfsx", "lfsu", "lfsux", # FP load single
289 "lfd", "lfdx", "lfdu", "lfdux", "lfiwzx", "lfiwax", # FP load double
290 "lha", "lharx", "lhau", "lhaux", "lhax", # load half
291 "lhbrx", "lhz", "lhzu", "lhzux", "lhzx", # more load half
292 #"lhabr", "lhaubr", # load half SVP64 bit-reversed
293 #"lhzbr", "lhzubr", # more load half SVP64 bit-reversed
294 "lwa", "lwarx", "lwaux", "lwax", "lwbrx", # load word
295 "lwz", "lwzcix", "lwzu", "lwzux", "lwzx", # more load word
296 #"lwabr", # load word SVP64 bit-reversed
297 #"lwzbr", "lwzubr", # more load word SVP64 bit-reversed
298 "maddhd", "maddhdu", "maddld", # INT multiply-and-add
299 "mcrf", "mcrxr", "mcrxrx", "mfcr/mfocrf", # CR mvs
300 "mfmsr", "mfspr",
301 "modsd", "modsw", "modud", "moduw",
302 "mtcrf/mtocrf", "mtmsr", "mtmsrd", "mtspr",
303 "mulhd", "mulhdu", "mulhw", "mulhwu", "mulld", "mulldo",
304 "mulli", "mullw", "mullwo",
305 "nand", "neg", "nego",
306 "nop",
307 "nor", "or", "orc", "ori", "oris",
308 "popcntb", "popcntd", "popcntw",
309 "prtyd", "prtyw",
310 "rfid",
311 "rldcl", "rldcr", "rldic", "rldicl", "rldicr", "rldimi",
312 "rlwimi", "rlwinm", "rlwnm",
313 "setb",
314 "setvl", # https://libre-soc.org/openpower/sv/setvl
315 "svremap", # https://libre-soc.org/openpower/sv/remap - TEMPORARY
316 "svshape", # https://libre-soc.org/openpower/sv/remap
317 "svstep", # https://libre-soc.org/openpower/sv/setvl
318 "sim_cfg",
319 "slbia", "sld", "slw", "srad", "sradi",
320 "sraw", "srawi", "srd", "srw",
321 "stb", "stbcix", "stbcx", "stbu", "stbux", "stbx",
322 "std", "stdbrx", "stdcx", "stdu", "stdux", "stdx",
323 "stfs", "stfsx", "stfsu", "stfux", "stfsux", # FP store single
324 "stfd", "stfdx", "stfdu", "stfdux", "stfiwx", # FP store double
325 "sth", "sthbrx", "sthcx", "sthu", "sthux", "sthx",
326 "stw", "stwbrx", "stwcx", "stwu", "stwux", "stwx",
327 "subf", "subfc", "subfco", "subfe", "subfeo", "subfic",
328 "subfme", "subfmeo", "subfo", "subfze", "subfzeo",
329 "sync",
330 "td", "tdi",
331 "tlbie", "tlbiel",
332 "tw", "twi",
333 "xor", "xori", "xoris",
334 ]
335
336 # two-way lookup of instruction-to-index and vice-versa
337 insns = {}
338 asmidx = {}
339 for i, insn in enumerate(_insns):
340 insns[i] = insn
341 asmidx[insn] = i
342
343 # must be long enough to cover all instructions
344 asmlen = len(_insns).bit_length()
345
346 # Internal Operation numbering. Add new opcodes here (FPADD, FPMUL etc.)
347
348
349 @unique
350 class MicrOp(Enum):
351 OP_ILLEGAL = 0 # important that this is zero (see power_decoder.py)
352 OP_NOP = 1
353 OP_ADD = 2
354 OP_ADDPCIS = 3
355 OP_AND = 4
356 OP_ATTN = 5
357 OP_B = 6
358 OP_BC = 7
359 OP_BCREG = 8
360 OP_BPERM = 9
361 OP_CMP = 10
362 OP_CMPB = 11
363 OP_CMPEQB = 12
364 OP_CMPRB = 13
365 OP_CNTZ = 14
366 OP_CRAND = 15
367 OP_CRANDC = 16
368 OP_CREQV = 17
369 OP_CRNAND = 18
370 OP_CRNOR = 19
371 OP_CROR = 20
372 OP_CRORC = 21
373 OP_CRXOR = 22
374 OP_DARN = 23
375 OP_DCBF = 24
376 OP_DCBST = 25
377 OP_DCBT = 26
378 OP_DCBTST = 27
379 OP_DCBZ = 28
380 OP_DIV = 29
381 OP_DIVE = 30
382 OP_EXTS = 31
383 OP_EXTSWSLI = 32
384 OP_ICBI = 33
385 OP_ICBT = 34
386 OP_ISEL = 35
387 OP_ISYNC = 36
388 OP_LOAD = 37
389 OP_STORE = 38
390 OP_MADDHD = 39
391 OP_MADDHDU = 40
392 OP_MADDLD = 41
393 OP_MCRF = 42
394 OP_MCRXR = 43
395 OP_MCRXRX = 44
396 OP_MFCR = 45
397 OP_MFSPR = 46
398 OP_MOD = 47
399 OP_MTCRF = 48
400 OP_MTSPR = 49
401 OP_MUL_L64 = 50
402 OP_MUL_H64 = 51
403 OP_MUL_H32 = 52
404 OP_OR = 53
405 OP_POPCNT = 54
406 OP_PRTY = 55
407 OP_RLC = 56
408 OP_RLCL = 57
409 OP_RLCR = 58
410 OP_SETB = 59
411 OP_SHL = 60
412 OP_SHR = 61
413 OP_SYNC = 62
414 OP_TRAP = 63
415 OP_XOR = 67
416 OP_SIM_CONFIG = 68
417 OP_CROP = 69
418 OP_RFID = 70
419 OP_MFMSR = 71
420 OP_MTMSRD = 72
421 OP_SC = 73
422 OP_MTMSR = 74
423 OP_TLBIE = 75
424 OP_SETVL = 76
425 OP_FPOP = 77 # temporary: replace with actual ops
426 OP_FPOP_I = 78 # temporary: replace with actual ops
427 OP_FP_MADD = 79
428 OP_SVREMAP = 80
429 OP_SVSHAPE = 81
430 OP_SVSTEP = 82
431 OP_ADDG6S = 83
432 OP_CDTBCD = 84
433 OP_CBCDTD = 85
434
435
436 @unique
437 class In1Sel(Enum):
438 NONE = 0
439 RA = 1
440 RA_OR_ZERO = 2
441 SPR = 3
442 RS = 4 # for some ALU/Logical operations
443 FRA = 5
444 FRS = 6
445
446
447 @unique
448 class In2Sel(Enum):
449 NONE = 0
450 RB = 1
451 CONST_UI = 2
452 CONST_SI = 3
453 CONST_UI_HI = 4
454 CONST_SI_HI = 5
455 CONST_LI = 6
456 CONST_BD = 7
457 CONST_DS = 8
458 CONST_M1 = 9
459 CONST_SH = 10
460 CONST_SH32 = 11
461 SPR = 12
462 RS = 13 # for shiftrot (M-Form)
463 FRB = 14
464 CONST_SVD = 15 # for SVD-Form
465 CONST_SVDS = 16 # for SVDS-Form
466
467
468 @unique
469 class In3Sel(Enum):
470 NONE = 0
471 RS = 1
472 RB = 2 # for shiftrot (M-Form)
473 FRS = 3
474 FRC = 4
475 RC = 5 # for SVP64 bit-reverse LD/ST
476
477
478 @unique
479 class OutSel(Enum):
480 NONE = 0
481 RT = 1
482 RA = 2
483 SPR = 3
484 RT_OR_ZERO = 4
485 FRT = 5
486 FRS = 6
487
488
489 @unique
490 class LdstLen(Enum):
491 NONE = 0
492 is1B = 1
493 is2B = 2
494 is4B = 4
495 is8B = 8
496
497
498 @unique
499 class LDSTMode(Enum):
500 NONE = 0
501 update = 1
502 cix = 2
503 cx = 3
504
505
506 @unique
507 class RC(Enum):
508 NONE = 0
509 ONE = 1
510 RC = 2
511
512
513 @unique
514 class CryIn(Enum):
515 ZERO = 0
516 ONE = 1
517 CA = 2
518 # TODO OV = 3
519
520
521 @unique
522 class CRInSel(Enum):
523 NONE = 0
524 CR0 = 1
525 BI = 2
526 BFA = 3
527 BA_BB = 4
528 BC = 5
529 WHOLE_REG = 6
530 CR1 = 7
531
532
533 @unique
534 class CROutSel(Enum):
535 NONE = 0
536 CR0 = 1
537 BF = 2
538 BT = 3
539 WHOLE_REG = 4
540 CR1 = 5
541
542
543 # SPRs - Special-Purpose Registers. See V3.0B Figure 18 p971 and
544 # http://libre-riscv.org/openpower/isatables/sprs.csv
545 # http://bugs.libre-riscv.org/show_bug.cgi?id=261
546
547 def get_spr_enum(full_file):
548 """get_spr_enum - creates an Enum of SPRs, dynamically
549 has the option to reduce the enum to a much shorter list.
550 this saves drastically on the size of the regfile
551 """
552 short_list = {'PIDR', 'DAR', 'PRTBL', 'DSISR', 'SVSRR0', 'SVSTATE',
553 'SVSTATE0', 'SVSTATE1', 'SVSTATE2', 'SVSTATE3',
554 'SPRG0_priv', 'SPRG1_priv', 'SPRG2_priv', 'SPRG3_priv',
555 'SPRG3'
556 }
557 spr_csv = []
558 for row in get_csv("sprs.csv"):
559 if full_file or row['SPR'] in short_list:
560 spr_csv.append(row)
561
562 spr_info = namedtuple('spr_info', 'SPR priv_mtspr priv_mfspr length idx')
563 spr_dict = {}
564 spr_byname = {}
565 for row in spr_csv:
566 info = spr_info(SPR=row['SPR'], priv_mtspr=row['priv_mtspr'],
567 priv_mfspr=row['priv_mfspr'], length=int(row['len']),
568 idx=int(row['Idx']))
569 spr_dict[int(row['Idx'])] = info
570 spr_byname[row['SPR']] = info
571 fields = [(row['SPR'], int(row['Idx'])) for row in spr_csv]
572 SPR = Enum('SPR', fields)
573 return SPR, spr_dict, spr_byname
574
575 SPRfull, spr_dict, spr_byname = get_spr_enum(full_file=True)
576 SPRreduced, _, _ = get_spr_enum(full_file=False)
577
578 XER_bits = {
579 'SO': 32,
580 'OV': 33,
581 'CA': 34,
582 'OV32': 44,
583 'CA32': 45
584 }
585
586 if __name__ == '__main__':
587 # find out what the heck is in SPR enum :)
588 print("sprs full", len(SPRfull))
589 print(dir(SPRfull))
590 print("sprs reduced", len(SPRreduced))
591 print(dir(SPRreduced))
592 print(dir(Enum))
593 print(SPRfull.__members__['TAR'])
594 for x in SPRfull:
595 print("full", x, x.value, str(x), x.name)
596 for x in SPRreduced:
597 print("reduced", x, x.value, str(x), x.name)
598
599 print("function", Function.ALU.name)