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