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