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