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