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