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