pysvp64db: fix traversal
[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 (
18 auto,
19 Enum as _Enum,
20 unique,
21 )
22 import csv
23 import os
24 from os.path import dirname, join
25 from collections import namedtuple
26 import functools
27
28
29 def find_wiki_dir():
30 filedir = os.path.dirname(os.path.abspath(__file__))
31 basedir = dirname(dirname(dirname(filedir)))
32 tabledir = join(basedir, 'openpower')
33 isatables = join(tabledir, 'isatables')
34 #print ("find_wiki_dir", isatables)
35 return isatables
36
37
38 def find_wiki_file(name):
39 return join(find_wiki_dir(), name)
40
41
42 def get_csv(name):
43 retval = _get_csv(name)
44 return [i.copy() for i in retval]
45
46
47 @functools.lru_cache()
48 def _get_csv(name):
49 """gets a not-entirely-csv-file-formatted database, which allows comments
50 """
51 file_path = find_wiki_file(name)
52 with open(file_path, 'r') as csvfile:
53 csvfile = filter(lambda row: row[0] !='#', csvfile) # strip "#..."
54 reader = csv.DictReader(csvfile)
55 return list(reader)
56
57
58 # names of the fields in the tables that don't correspond to an enum
59 single_bit_flags = ['inv A', 'inv out',
60 'cry out', 'BR', 'sgn ext', 'rsrv', '32b',
61 'sgn', 'lk', 'sgl pipe']
62
63 # default values for fields in the table
64 default_values = {'unit': "NONE", 'internal op': "OP_ILLEGAL",
65 'in1': "RA", 'in2': 'NONE', 'in3': 'NONE', 'out': 'NONE',
66 'CR in': 'NONE',
67 'ldst len': 'NONE',
68 'upd': '0',
69 'rc': 'NONE', 'cry in': 'ZERO', 'form': 'NONE'}
70
71
72 def get_signal_name(name):
73 if name[0].isdigit():
74 name = "is_" + name
75 return name.lower().replace(' ', '_')
76
77
78 class Enum(_Enum):
79 @classmethod
80 def _missing_(cls, desc):
81 if isinstance(desc, str):
82 try:
83 if desc == "":
84 desc = 0
85 else:
86 desc = int(desc, 0)
87 except ValueError:
88 pass
89 keys = {item.name:item for item in cls}
90 descs = {item.value:item for item in cls}
91 return keys.get(desc, descs.get(desc))
92
93
94 # this corresponds to which Function Unit (pipeline-with-Reservation-Stations)
95 # is to process and guard the operation. they are roughly divided by having
96 # the same register input/output signature (X-Form, etc.)
97
98
99 @unique
100 class Function(Enum):
101 NONE = 0
102 ALU = 1 << 1
103 LDST = 1 << 2
104 SHIFT_ROT = 1 << 3
105 LOGICAL = 1 << 4
106 BRANCH = 1 << 5
107 CR = 1 << 6
108 TRAP = 1 << 7
109 MUL = 1 << 8
110 DIV = 1 << 9
111 SPR = 1 << 10
112 MMU = 1 << 11
113 SV = 1 << 12 # Simple-V https://libre-soc.org/openpower/sv
114 VL = 1 << 13 # setvl
115 FPU = 1 << 14 # FPU
116
117 @functools.lru_cache(maxsize=None)
118 def __repr__(self):
119 counter = 0
120 value = int(self.value)
121 if value != 0:
122 while value != 0:
123 counter += 1
124 value >>= 1
125 counter -= 1
126 desc = f"(1 << {counter})"
127 else:
128 desc = "0"
129 return f"<{self.__class__.__name__}.{self.name}: {desc}>"
130
131
132 @unique
133 class Form(Enum):
134 NONE = 0
135 I = 1
136 B = 2
137 SC = 3
138 D = 4
139 DS = 5
140 DQ = 6
141 DX = 7
142 X = 8
143 XL = 9
144 XFX = 10
145 XFL = 11
146 XX1 = 12
147 XX2 = 13
148 XX3 = 14
149 XX4 = 15
150 XS = 16
151 XO = 17
152 A = 18
153 M = 19
154 MD = 20
155 MDS = 21
156 VA = 22
157 VC = 23
158 VX = 24
159 EVX = 25
160 EVS = 26
161 Z22 = 27
162 Z23 = 28
163 SVL = 29 # Simple-V for setvl instruction
164 SVD = 30 # Simple-V for LD/ST bit-reverse, variant of D-Form
165 SVDS = 31 # Simple-V for LD/ST bit-reverse, variant of DS-Form
166 SVM = 32 # Simple-V SHAPE mode
167 SVM2 = 33 # Simple-V SHAPE2 mode - fits into SVM
168 SVRM = 34 # Simple-V REMAP mode
169 TLI = 35 # ternlogi
170 # 36 available
171 BM2 = 37 # bmask
172 SVI = 38 # Simple-V Index Mode
173 VA2 = 39
174 SVC = 40
175 SVR = 41
176 CRB = 42 # crternlogi / crbinlut
177 MM = 43 # [f]minmax[s][.]
178 CW = 44
179 CW2 = 45
180 DCT = 46 # fdmadds
181
182 # Simple-V svp64 fields https://libre-soc.org/openpower/sv/svp64/
183
184
185 class SVMode(Enum):
186 NONE = 0 # for non-SV instructions only
187 NORMAL = auto()
188 LDST_IDX = auto()
189 LDST_IMM = auto()
190 BRANCH = auto()
191 CROP = auto()
192
193
194 @unique
195 class SVPType(Enum):
196 NONE = 0
197 P1 = 1
198 P2 = 2
199 P2M = 3 # for mixed EXTRA3/3/2 where MASK_SRC is RM[6,7,18]
200
201 @classmethod
202 def _missing_(cls, desc):
203 return {"1P": SVPType.P1, "2P": SVPType.P2, "2PM": SVPType.P2M}.get(desc)
204
205 def __str__(self):
206 return {
207 SVPType.NONE: "NONE",
208 SVPType.P1: "1P",
209 SVPType.P2: "2P",
210 SVPType.P2M: "2PM",
211 }[self]
212
213
214 @unique
215 class SVEType(Enum):
216 """SVEType
217 * EXTRA2 : 0: [10,11] 1: [12,13] 2: [14,15] 3: [16,17] unused: [18]
218 * EXTRA3 : 0: [10,11,12] 1: [13,14,15] mask: [16,17,18]
219 * EXTRA32: 0: [10,11,12] 1: [13,14,15] 2: [16,17] mask: [6,7,18]
220 """
221 NONE = 0
222 EXTRA2 = 1
223 EXTRA3 = 2
224 EXTRA32 = 3 # mixed EXTRA3 and EXTRA2 using RM bits 6&7 for MASK_SRC
225
226 def __str__(self):
227 return self.name
228
229
230 @unique
231 class SVMaskSrc(Enum):
232 NO = 0
233 EN = 1
234
235 def __str__(self):
236 return self.name
237
238
239 @unique
240 class SVExtra(Enum):
241 NONE = 0
242 Idx0 = 1
243 Idx1 = 2
244 Idx2 = 3
245 Idx3 = 4
246 Idx_1_2 = 5 # due to weird BA/BB for crops
247
248 def __str__(self):
249 return {
250 SVExtra.NONE: "NONE",
251 SVExtra.Idx0: "EXTRA0",
252 SVExtra.Idx1: "EXTRA1",
253 SVExtra.Idx2: "EXTRA2",
254 SVExtra.Idx3: "EXTRA3",
255 SVExtra.Idx_1_2: "EXTRA1/EXTRA2",
256 }[self]
257
258 # Backward compatibility
259 SVEXTRA = SVExtra
260
261
262 class Reg(Enum):
263 NONE = auto()
264 RA = auto()
265 RA_OR_ZERO = auto()
266 RB = auto()
267 RC = auto()
268 RS = auto()
269 RT = auto()
270 RT_OR_ZERO = auto()
271 FRA = auto()
272 FRB = auto()
273 FRC = auto()
274 FRS = auto()
275 FRT = auto()
276 CR = auto()
277 CR0 = auto()
278 CR1 = auto()
279 BF = auto()
280 BFA = auto()
281 BFB = auto()
282 BA = auto()
283 BB = auto()
284 BC = auto()
285 BI = auto()
286 BT = auto()
287 BFT = auto()
288 WHOLE_REG = auto()
289 SPR = auto()
290 RSp = auto()
291 RTp = auto()
292 FRAp = auto()
293 FRBp = auto()
294 FRSp = auto()
295 FRTp = auto()
296
297 def __str__(self):
298 return self.name
299
300 @classmethod
301 def _missing_(cls, desc):
302 selectors = (
303 In1Sel, In2Sel, In3Sel, CRInSel, CRIn2Sel,
304 OutSel, CROutSel,
305 )
306 if isinstance(desc, selectors):
307 return cls.__members__.get(desc.name)
308
309 return cls.__members__.get(desc)
310
311 @property
312 def alias(self):
313 alias = {
314 Reg.RSp: Reg.RS,
315 Reg.RTp: Reg.RT,
316 Reg.FRAp: Reg.FRA,
317 Reg.FRBp: Reg.FRB,
318 Reg.FRSp: Reg.FRS,
319 Reg.FRTp: Reg.FRT,
320 }.get(self)
321 if alias is not None:
322 return alias
323
324 alias = {
325 Reg.RA_OR_ZERO: Reg.RA,
326 Reg.RT_OR_ZERO: Reg.RT,
327 }.get(self)
328 if alias is not None:
329 return alias
330
331 return self
332
333 @property
334 def or_zero(self):
335 return (self in (
336 Reg.RA_OR_ZERO,
337 Reg.RT_OR_ZERO,
338 ))
339
340 @property
341 def pair(self):
342 return (self in (
343 Reg.RSp,
344 Reg.RTp,
345 Reg.FRAp,
346 Reg.FRBp,
347 Reg.FRSp,
348 Reg.FRTp,
349 ))
350
351
352 @unique
353 class SVP64PredMode(Enum):
354 ALWAYS = 0
355 INT = 1
356 CR = 2
357 RC1 = 3
358
359
360 @unique
361 class SVP64PredInt(Enum):
362 ALWAYS = 0b000
363 R3_UNARY = 0b001
364 R3 = 0b010
365 R3_N = 0b011
366 R10 = 0b100
367 R10_N = 0b101
368 R30 = 0b110
369 R30_N = 0b111
370
371 @classmethod
372 def _missing_(cls, desc):
373 if isinstance(desc, str):
374 value = desc
375 values = {
376 "^r3": cls.R3_UNARY,
377 "r3": cls.R3,
378 "~r3": cls.R3_N,
379 "r10": cls.R10,
380 "~r10": cls.R10_N,
381 "r30": cls.R30,
382 "~r30": cls.R30_N,
383 }
384 if value.startswith("~"):
385 value = f"~{value[1:].strip()}"
386 elif "<<" in value: # 1 << r3
387 (lhs, _, rhs) = value.partition("<<")
388 lhs = lhs.strip().lower()
389 rhs = rhs.strip().lower()
390 if (lhs == "1") and (rhs in ("r3", "%r3")):
391 value = "^r3"
392
393 return values.get(value)
394
395 return super()._missing_(desc)
396
397 def __str__(self):
398 return {
399 self.__class__.ALWAYS: "",
400 self.__class__.R3_UNARY: "^r3",
401 self.__class__.R3: "r3",
402 self.__class__.R3_N: "~r3",
403 self.__class__.R10: "r10",
404 self.__class__.R10_N: "~r10",
405 self.__class__.R30: "r30",
406 self.__class__.R30_N: "~r30",
407 }[self]
408
409 def __repr__(self):
410 return f"{self.__class__.__name__}({str(self)})"
411
412 def __int__(self):
413 return self.value
414
415 @property
416 def mode(self):
417 return SVP64PredMode.INT
418
419 @property
420 def inv(self):
421 return (self.value & 0b1)
422
423 @property
424 def state(self):
425 return (self.value >> 1)
426
427
428 class SVP64PredCR(Enum):
429 LT = 0
430 GE = 1
431 NL = GE
432 GT = 2
433 LE = 3
434 NG = LE
435 EQ = 4
436 NE = 5
437 SO = 6
438 UN = SO
439 NS = 7
440 NU = NS
441
442 @classmethod
443 def _missing_(cls, desc):
444 if isinstance(desc, str):
445 name = desc.upper()
446 return cls.__members__.get(name)
447
448 return super()._missing_(desc)
449
450 def __int__(self):
451 return self.value
452
453 @property
454 def mode(self):
455 return SVP64PredMode.CR
456
457 @property
458 def inv(self):
459 return (self.value & 0b1)
460
461 @property
462 def state(self):
463 return (self.value >> 1)
464
465
466 @unique
467 class SVP64PredRC1(Enum):
468 RC1 = 0
469 RC1_N = 1
470
471 @classmethod
472 def _missing_(cls, desc):
473 return {
474 "RC1": SVP64PredRC1.RC1,
475 "~RC1": SVP64PredRC1.RC1_N,
476 }.get(desc)
477
478 def __int__(self):
479 return 1
480
481 @property
482 def mode(self):
483 return SVP64PredMode.RC1
484
485 @property
486 def inv(self):
487 return (self is SVP64PredRC1.RC1_N)
488
489 @property
490 def state(self):
491 return 1
492
493
494 class SVP64Pred(Enum):
495 ALWAYS = SVP64PredInt.ALWAYS
496 R3_UNARY = SVP64PredInt.R3_UNARY
497 R3 = SVP64PredInt.R3
498 R3_N = SVP64PredInt.R3_N
499 R10 = SVP64PredInt.R10
500 R10_N = SVP64PredInt.R10_N
501 R30 = SVP64PredInt.R30
502 R30_N = SVP64PredInt.R30_N
503
504 LT = SVP64PredCR.LT
505 GE = SVP64PredCR.GE
506 GT = SVP64PredCR.GT
507 LE = SVP64PredCR.LE
508 EQ = SVP64PredCR.EQ
509 NE = SVP64PredCR.NE
510 SO = SVP64PredCR.SO
511 NS = SVP64PredCR.NS
512
513 RC1 = SVP64PredRC1.RC1
514 RC1_N = SVP64PredRC1.RC1_N
515
516 @classmethod
517 def _missing_(cls, desc):
518 if isinstance(desc, str):
519 values = {item.value:item for item in cls}
520 for subcls in (SVP64PredInt, SVP64PredCR, SVP64PredRC1):
521 try:
522 return values.get(subcls(desc))
523 except ValueError:
524 pass
525 return None
526
527 return super()._missing_(desc)
528
529 def __int__(self):
530 return int(self.value)
531
532 @property
533 def mode(self):
534 return self.value.mode
535
536 @property
537 def inv(self):
538 return self.value.inv
539
540 @property
541 def state(self):
542 return self.value.state
543
544
545 @unique
546 class SVP64RMMode(Enum):
547 NORMAL = 0
548 MAPREDUCE = 1
549 FFIRST = 2
550 SATURATE = 3
551 BRANCH = 5
552
553
554 @unique
555 class SVP64BCPredMode(Enum):
556 NONE = 0
557 MASKZERO = 1
558 MASKONE = 2
559
560
561 @unique
562 class SVP64BCVLSETMode(Enum):
563 NONE = 0
564 VL_INCL = 1
565 VL_EXCL = 2
566
567
568 # note that these are chosen to be exactly the same as
569 # SVP64 RM bit 4. ALL=1 => bit4=1
570 @unique
571 class SVP64BCGate(Enum):
572 ANY = 0
573 ALL = 1
574
575
576 class SVP64BCCTRMode(Enum):
577 NONE = 0
578 TEST = 1
579 TEST_INV = 2
580
581
582 @unique
583 class SVP64Width(Enum):
584 DEFAULT = 0
585 EW_32 = 1
586 EW_16 = 2
587 EW_8 = 3
588
589 @classmethod
590 def _missing_(cls, desc):
591 if isinstance(desc, str):
592 return {
593 "32": SVP64Width.EW_32,
594 "16": SVP64Width.EW_16,
595 "8": SVP64Width.EW_8,
596 }.get(desc)
597
598 return super()._missing_(desc)
599
600
601 @unique
602 class SVP64SubVL(Enum):
603 VEC1 = 0
604 VEC2 = 1
605 VEC3 = 2
606 VEC4 = 3
607
608 @classmethod
609 def _missing_(cls, desc):
610 if isinstance(desc, str):
611 name = desc.upper()
612 return cls.__members__.get(name)
613
614 return super()._missing_(desc)
615
616
617 @unique
618 class SVP64Sat(Enum):
619 NONE = 0
620 SIGNED = 1
621 UNSIGNED = 2
622
623
624 @unique
625 class SVP64LDSTmode(Enum):
626 NONE = 0
627 INDEXED = 1
628 ELSTRIDE = 2
629 UNITSTRIDE = 3
630
631
632 class RegType(Enum):
633 GPR = 0
634 RA = GPR
635 RB = GPR
636 RC = GPR
637 RS = GPR
638 RSp = RS
639 RT = GPR
640 RTp = RT
641
642 FPR = 1
643 FRA = FPR
644 FRAp = FRA
645 FRB = FPR
646 FRBp = FRB
647 FRC = FPR
648 FRS = FPR
649 FRSp = FRS
650 FRT = FPR
651 FRTp = FRT
652
653 CR_3BIT = 2 # CR field; the CR register is 32-bit
654 BF = CR_3BIT
655 BFA = CR_3BIT
656 BFB = CR_3BIT
657
658 CR_5BIT = 3 # bit of the 32-bit CR register
659 BA = CR_5BIT
660 BB = CR_5BIT
661 BC = CR_5BIT
662 BI = CR_5BIT
663 BT = CR_5BIT
664
665 XER_BIT = 4 # XER bits, includes OV, OV32, SO, CA, CA32
666 OV = XER_BIT
667 OV32 = XER_BIT
668 CA = XER_BIT
669 CA32 = XER_BIT
670 SO = XER_BIT
671
672 @classmethod
673 def _missing_(cls, value):
674 if isinstance(value, Reg):
675 return cls.__members__.get(value.name)
676
677 return super()._missing_(value)
678
679
680 FPTRANS_INSNS = (
681 "fatan2", "fatan2s",
682 "fatan2pi", "fatan2pis",
683 "fpow", "fpows",
684 "fpown", "fpowns",
685 "fpowr", "fpowrs",
686 "frootn", "frootns",
687 "fhypot", "fhypots",
688 "frsqrt", "frsqrts",
689 "fcbrt", "fcbrts",
690 "frecip", "frecips",
691 "fexp2m1", "fexp2m1s",
692 "flog2p1", "flog2p1s",
693 "fexp2", "fexp2s",
694 "flog2", "flog2s",
695 "fexpm1", "fexpm1s",
696 "flogp1", "flogp1s",
697 "fexp", "fexps",
698 "flog", "flogs",
699 "fexp10m1", "fexp10m1s",
700 "flog10p1", "flog10p1s",
701 "fexp10", "fexp10s",
702 "flog10", "flog10s",
703 "fsin", "fsins",
704 "fcos", "fcoss",
705 "ftan", "ftans",
706 "fasin", "fasins",
707 "facos", "facoss",
708 "fatan", "fatans",
709 "fsinpi", "fsinpis",
710 "fcospi", "fcospis",
711 "ftanpi", "ftanpis",
712 "fasinpi", "fasinpis",
713 "facospi", "facospis",
714 "fatanpi", "fatanpis",
715 "fsinh", "fsinhs",
716 "fcosh", "fcoshs",
717 "ftanh", "ftanhs",
718 "fasinh", "fasinhs",
719 "facosh", "facoshs",
720 "fatanh", "fatanhs",
721 "fminmax",
722 "fmod", "fmods",
723 "fremainder", "fremainders",
724 )
725
726
727 # supported instructions: make sure to keep up-to-date with CSV files
728 # just like everything else
729 _insns = [
730 "NONE", "add", "addc", "addco", "adde", "addeo",
731 "addi", "addic", "addic.", "addis",
732 "addme", "addmeo", "addo", "addze", "addzeo",
733 "addex",
734 "addg6s",
735 "and", "andc", "andi.", "andis.",
736 "attn",
737 "absdu", "absds", # AV bitmanip
738 "absdacs", "absdacu", # AV bitmanip
739 "avgadd", # AV bitmanip
740 "b", "bc", "bcctr", "bclr", "bctar",
741 "brh", "brw", "brd",
742 "bmask", # AV bitmanip
743 "bpermd",
744 "cbcdtd",
745 "cdtbcd",
746 "cfuged",
747 "cmp", "cmpb", "cmpeqb", "cmpi", "cmpl", "cmpli", "cmprb",
748 "cntlzd", "cntlzdm", "cntlzw", "cnttzd", "cnttzdm", "cnttzw",
749 "cprop", # AV bitmanip
750 "crand", "crandc", "creqv",
751 "crnand", "crnor", "cror", "crorc", "crxor",
752 "crbinlog", "crfbinlog", # binary bitmanip (field and CR bit)
753 "crternlogi", "crfternlogi", # ternary bitmanip (field and CR bit)
754 "darn",
755 "dcbf", "dcbst", "dcbt", "dcbtst", "dcbz",
756 "divd", "divde", "divdeo", "divdeu",
757 "divdeuo", "divdo", "divdu", "divduo",
758 "divmod2du",
759 "divw", "divwe", "divweo",
760 "divweu", "divweuo", "divwo", "divwu", "divwuo",
761 "dsld", "dsld.", "dsrd", "dsrd.",
762 "eieio", "eqv",
763 "extsb", "extsh", "extsw", "extswsli",
764 "fadd", "fadds", "fsub", "fsubs", # FP add / sub
765 "fcfids", "fcfidus", "fsqrts", "fres", "frsqrtes", # FP stuff
766 "fdmadds", # DCT FP 3-arg
767 "fmsubs", "fmadds", "fnmsubs", "fnmadds", # FP 3-arg
768 "ffadds", "ffsubs", "ffmuls", "ffdivs", # FFT FP 2-arg
769 "ffmsubs", "ffmadds", "ffnmsubs", "ffnmadds", # FFT FP 3-arg
770 "fmul", "fmuls", "fdiv", "fdivs", # FP mul / div
771 "fmr", "fabs", "fnabs", "fneg", "fcpsgn", # FP move/abs/neg
772 "fmvis", # FP load immediate
773 "fishmv", # Float Replace Lower-Half Single, Immediate
774 "gbbd", # bitmanip - (aka bmatflip)
775 "cffpr", "cffpro",
776 "mffpr", "mffprs",
777 "ctfpr", "ctfprs",
778 "mtfpr", "mtfprs",
779 "hrfid", "icbi", "icbt", "isel", "isync",
780 "lbarx", "lbz", "lbzcix", "lbzu", "lbzux", "lbzx", # load byte
781 "ld", "ldarx", "ldbrx", "ldu", "ldux", "ldx", # load double
782 # "lbzbr", "lbzubr", # load byte SVP64 bit-reversed
783 # "ldbr", "ldubr", # load double SVP64 bit-reversed
784 "lfs", "lfsx", "lfsu", "lfsux", # FP load single
785 "lfd", "lfdx", "lfdu", "lfdux", "lfiwzx", "lfiwax", # FP load double
786 "lha", "lharx", "lhau", "lhaux", "lhax", # load half
787 "lhbrx", "lhz", "lhzu", "lhzux", "lhzx", # more load half
788 # "lhabr", "lhaubr", # load half SVP64 bit-reversed
789 # "lhzbr", "lhzubr", # more load half SVP64 bit-reversed
790 "lwa", "lwarx", "lwaux", "lwax", "lwbrx", # load word
791 "lwz", "lwzcix", "lwzu", "lwzux", "lwzx", # more load word
792 # "lwabr", # load word SVP64 bit-reversed
793 # "lwzbr", "lwzubr", # more load word SVP64 bit-reversed
794 "maddedu", "maddedus",
795 "maddhd", "maddhdu", "maddld", # INT multiply-and-add
796 "maddsubrs", # Int DCT Butterfly Add Sub and Round Shift
797 "maddrs", # Int DCT Butterfly Add and Accumulate and Round Shift
798 "msubrs", # Int DCT Butterfly Subtract from and Round Shift
799 "mcrf", "mcrxr", "mcrxrx", "mfcr/mfocrf", # CR mvs
800 "mfmsr", "mfspr",
801 "minmax", # AV bitmanip
802 "modsd", "modsw", "modud", "moduw",
803 "mtcrf/mtocrf", "mtmsr", "mtmsrd", "mtspr",
804 "mulhd", "mulhdu", "mulhw", "mulhwu", "mulld", "mulldo",
805 "mulli", "mullw", "mullwo",
806 "nand", "neg", "nego",
807 "nop",
808 "nor", "or", "orc", "ori", "oris",
809 "pcdec",
810 "pdepd", "pextd",
811 "popcntb", "popcntd", "popcntw",
812 "prtyd", "prtyw",
813 "rfid",
814 "rldcl", "rldcr", "rldic", "rldicl", "rldicr", "rldimi",
815 "rlwimi", "rlwinm", "rlwnm",
816 "setb",
817 "setbc", "setbcr", "setnbc", "setnbcr",
818 "setvl", # https://libre-soc.org/openpower/sv/setvl
819 "sc", "scv",
820 "svindex", # https://libre-soc.org/openpower/sv/remap
821 "svremap", # https://libre-soc.org/openpower/sv/remap - TEMPORARY
822 "svshape", # https://libre-soc.org/openpower/sv/remap/#svshape
823 "svshape2", # https://libre-soc.org/openpower/sv/remap/discussion TODO
824 "svstep", # https://libre-soc.org/openpower/sv/setvl
825 "sim_cfg",
826 "sadd", "saddw", "sadduw",
827 "slbia", "sld", "slw", "srad", "sradi",
828 "sraw", "srawi", "srd", "srw",
829 "stb", "stbcix", "stbcx", "stbu", "stbux", "stbx",
830 "std", "stdbrx", "stdcx", "stdu", "stdux", "stdx",
831 "stfs", "stfsx", "stfsu", "stfux", "stfsux", # FP store single
832 "stfd", "stfdx", "stfdu", "stfdux", "stfiwx", # FP store double
833 "sth", "sthbrx", "sthcx", "sthu", "sthux", "sthx",
834 "stw", "stwbrx", "stwcx", "stwu", "stwux", "stwx",
835 "subf", "subfc", "subfco", "subfe", "subfeo", "subfic",
836 "subfme", "subfmeo", "subfo", "subfze", "subfzeo",
837 "sync",
838 "binlog", "ternlogi", # binary/ternary (lut2/lut3)
839 "td", "tdi",
840 "tlbie", "tlbiel", "tlbsync",
841 "tw", "twi",
842 "wait",
843 "xor", "xori", "xoris",
844 *FPTRANS_INSNS,
845 ]
846
847 # two-way lookup of instruction-to-index and vice-versa
848 insns = {}
849 asmidx = {}
850 for i, insn in enumerate(_insns):
851 insns[i] = insn
852 asmidx[insn] = i
853
854 # must be long enough to cover all instructions
855 asmlen = len(_insns).bit_length()
856
857 # Internal Operation numbering. Add new opcodes here (FPADD, FPMUL etc.)
858
859
860 @unique
861 class MicrOp(Enum):
862 OP_ILLEGAL = 0 # important that this is zero (see power_decoder.py)
863 OP_NOP = 1
864 OP_ADD = 2
865 OP_ADDPCIS = 3
866 OP_AND = 4
867 OP_ATTN = 5
868 OP_B = 6
869 OP_BC = 7
870 OP_BCREG = 8
871 OP_BPERM = 9
872 OP_CMP = 10
873 OP_CMPB = 11
874 OP_CMPEQB = 12
875 OP_CMPRB = 13
876 OP_CNTZ = 14
877 OP_CRAND = 15
878 OP_CRANDC = 16
879 OP_CREQV = 17
880 OP_CRNAND = 18
881 OP_CRNOR = 19
882 OP_CROR = 20
883 OP_CRORC = 21
884 OP_CRXOR = 22
885 OP_DARN = 23
886 OP_DCBF = 24
887 OP_DCBST = 25
888 OP_DCBT = 26
889 OP_DCBTST = 27
890 OP_DCBZ = 28
891 OP_DIV = 29
892 OP_DIVE = 30
893 OP_EXTS = 31
894 OP_EXTSWSLI = 32
895 OP_ICBI = 33
896 OP_ICBT = 34
897 OP_ISEL = 35
898 OP_ISYNC = 36
899 OP_LOAD = 37
900 OP_STORE = 38
901 OP_MADDHD = 39
902 OP_MADDHDU = 40
903 OP_MADDLD = 41
904 OP_MCRF = 42
905 OP_MCRXR = 43
906 OP_MCRXRX = 44
907 OP_MFCR = 45
908 OP_MFSPR = 46
909 OP_MOD = 47
910 OP_MTCRF = 48
911 OP_MTSPR = 49
912 OP_MUL_L64 = 50
913 OP_MUL_H64 = 51
914 OP_MUL_H32 = 52
915 OP_OR = 53
916 OP_POPCNT = 54
917 OP_PRTY = 55
918 OP_RLC = 56
919 OP_RLCL = 57
920 OP_RLCR = 58
921 OP_SETB = 59
922 OP_SHL = 60
923 OP_SHR = 61
924 OP_SYNC = 62
925 OP_TRAP = 63
926 OP_XOR = 67
927 OP_SIM_CONFIG = 68
928 OP_CROP = 69
929 OP_RFID = 70
930 OP_MFMSR = 71
931 OP_MTMSRD = 72
932 OP_SC = 73
933 OP_MTMSR = 74
934 OP_TLBIE = 75
935 OP_SETVL = 76
936 OP_FPOP = 77 # temporary: replace with actual ops
937 OP_FPOP_I = 78 # temporary: replace with actual ops
938 OP_FP_MADD = 79
939 OP_SVREMAP = 80
940 OP_SVSHAPE = 81
941 OP_SVSTEP = 82
942 OP_ADDG6S = 83
943 OP_CDTBCD = 84
944 OP_CBCDTD = 85
945 OP_TERNLOG = 86
946 OP_FETCH_FAILED = 87
947 # 88 available
948 OP_MINMAX = 89
949 OP_AVGADD = 90
950 OP_ABSDIFF = 91
951 OP_ABSADD = 92
952 OP_CPROP = 93
953 OP_BMASK = 94
954 OP_SVINDEX = 95
955 OP_FMVIS = 96
956 OP_FISHMV = 97
957 OP_PCDEC = 98
958 OP_MADDEDU = 99
959 OP_DIVMOD2DU = 100
960 OP_DSHL = 101
961 OP_DSHR = 102
962 OP_SHADD = 103
963 OP_MADDSUBRS = 104
964 OP_MADDRS = 105
965 OP_MSUBRS = 106
966 OP_BYTEREV = 107
967 OP_CFUGE = 108
968 OP_PDEP = 109
969 OP_PEXT = 110
970 OP_SETBC = 111
971 OP_BMAT = 112 # bmatflip/xor/and - known by many names (vgbbd in Power)
972 OP_CRTERNLOG = 113
973 OP_BINLOG = 114
974 OP_CRBINLOG = 115
975 OP_CRFBINLOG = 116
976 OP_CRFTERNLOG = 117
977
978
979 class SelType(Enum):
980 NONE = None
981 SRC = 's'
982 DST = 'd'
983
984 def __str__(self):
985 return {
986 SelType.NONE: "NONE",
987 SelType.SRC: "SRC",
988 SelType.DST: "DST",
989 }[self]
990
991
992 class In1Sel(Enum):
993 NONE = 0
994 RA = 1
995 RA_OR_ZERO = 2
996 SPR = 3
997 RS = 4 # for some ALU/Logical operations
998 RSp = RS
999 FRA = 5
1000 FRAp = FRA
1001 FRS = 6
1002 FRSp = FRS
1003 FRT = 7
1004 CIA = 8 # for addpcis
1005 RT = 9
1006
1007 def __str__(self):
1008 if self is In1Sel.RA_OR_ZERO:
1009 return "RA0"
1010 return self.name
1011
1012 @property
1013 def type(self):
1014 if self is In1Sel.NONE:
1015 return SelType.NONE
1016 return SelType.SRC
1017
1018
1019 class In2Sel(Enum):
1020 NONE = 0
1021 RB = 1
1022 CONST_UI = 2
1023 CONST_SI = 3
1024 CONST_UI_HI = 4
1025 CONST_SI_HI = 5
1026 CONST_LI = 6
1027 CONST_BD = 7
1028 CONST_DS = 8
1029 CONST_M1 = 9
1030 CONST_SH = 10
1031 CONST_SH32 = 11
1032 SPR = 12
1033 RS = 13 # for shiftrot (M-Form)
1034 RSp = RS
1035 FRB = 14
1036 FRBp = FRB
1037 CONST_SVD = 15 # for SVD-Form
1038 CONST_SVDS = 16 # for SVDS-Form
1039 # 17 available
1040 CONST_DXHI4 = 18 # for addpcis
1041 CONST_DQ = 19 # for ld/st-quad
1042
1043 def __str__(self):
1044 return self.name
1045
1046 @property
1047 def type(self):
1048 if self is In2Sel.NONE:
1049 return SelType.NONE
1050 return SelType.SRC
1051
1052
1053 class In3Sel(Enum):
1054 NONE = 0
1055 RS = 1
1056 RSp = RS
1057 RB = 2 # for shiftrot (M-Form)
1058 FRS = 3
1059 FRSp = FRS
1060 FRC = 4
1061 RC = 5 # for SVP64 bit-reverse LD/ST
1062 RT = 6 # for ternlog[i]
1063 RTp = RT
1064 FRA = 7
1065
1066 def __str__(self):
1067 return self.name
1068
1069 @property
1070 def type(self):
1071 if self is In3Sel.NONE:
1072 return SelType.NONE
1073 return SelType.SRC
1074
1075
1076 class OutSel(Enum):
1077 NONE = 0
1078 RT = 1
1079 RTp = RT
1080 RA = 2
1081 SPR = 3
1082 RT_OR_ZERO = 4
1083 FRT = 5
1084 FRTp = FRT
1085 FRS = 6
1086 FRSp = FRS
1087 RS = 7
1088 RSp = RS
1089 FRA = 8
1090
1091 def __str__(self):
1092 if self is OutSel.RT_OR_ZERO:
1093 return "RT0"
1094 return self.name
1095
1096 @property
1097 def type(self):
1098 if self is OutSel.NONE:
1099 return SelType.NONE
1100 return SelType.DST
1101
1102
1103 @unique
1104 class LDSTLen(Enum):
1105 NONE = 0
1106 is1B = 1
1107 is2B = 2
1108 is4B = 4
1109 is8B = 8
1110
1111 # Backward compatibility
1112 LdstLen = LDSTLen
1113
1114
1115 @unique
1116 class LDSTMode(Enum):
1117 NONE = 0
1118 update = 1
1119 cix = 2
1120 cx = 3
1121
1122
1123 @unique
1124 class RCOE(Enum):
1125 NONE = 0
1126 ONE = 1
1127 RC = 2 # includes OE
1128 RC_ONLY = 3 # does not include OE
1129
1130
1131 @unique
1132 class CryIn(Enum):
1133 ZERO = 0
1134 ONE = 1
1135 CA = 2
1136 OV = 3
1137
1138
1139 @unique
1140 class CRInSel(Enum):
1141 NONE = 0
1142 CR0 = 1
1143 BI = 2
1144 BFA = 3
1145 BA_BB = 4
1146 BC = 5
1147 WHOLE_REG = 6
1148 CR1 = 7
1149 BA = 8
1150 BFA_BFB_BF = 9
1151 BA_BFB = 10 # maaamma miiia... definitely time for CRin1/2 in CSV...
1152
1153 def __str__(self):
1154 return self.name
1155
1156 @property
1157 def type(self):
1158 if self is CRInSel.NONE:
1159 return SelType.NONE
1160 return SelType.SRC
1161
1162
1163 @unique
1164 class CRIn2Sel(Enum):
1165 NONE = 0
1166 BB = 1
1167 BFB = 2
1168
1169 def __str__(self):
1170 return self.name
1171
1172 @property
1173 def type(self):
1174 if self is CRIn2Sel.NONE:
1175 return SelType.NONE
1176 return SelType.SRC
1177
1178
1179 @unique
1180 class CROutSel(Enum):
1181 NONE = 0
1182 CR0 = 1
1183 BF = 2
1184 BT = 3
1185 WHOLE_REG = 4
1186 CR1 = 5
1187
1188 def __str__(self):
1189 return self.name
1190
1191 @property
1192 def type(self):
1193 if self is CROutSel.NONE:
1194 return SelType.NONE
1195 return SelType.DST
1196
1197
1198 # SPRs - Special-Purpose Registers. See V3.0B Figure 18 p971 and
1199 # http://libre-riscv.org/openpower/isatables/sprs.csv
1200 # http://bugs.libre-riscv.org/show_bug.cgi?id=261
1201 # http://bugs.libre-riscv.org/show_bug.cgi?id=859 - KAIVB
1202
1203 def get_spr_enum(full_file):
1204 """get_spr_enum - creates an Enum of SPRs, dynamically
1205 has the option to reduce the enum to a much shorter list.
1206 this saves drastically on the size of the regfile
1207 """
1208 short_list = {'PIDR', 'DAR', 'PRTBL', 'DSISR', 'SVSRR0', 'SVSTATE',
1209 'SVSTATE0', 'SVSTATE1', 'SVSTATE2', 'SVSTATE3',
1210 'SPRG0_priv', 'SPRG1_priv', 'SPRG2_priv', 'SPRG3_priv',
1211 'SPRG0', 'SPRG1', 'SPRG2', 'SPRG3', 'KAIVB',
1212 # hmmm should not be including these, they are FAST regs
1213 'CTR', 'LR', 'TAR', 'SRR0', 'SRR1', 'XER', 'DEC', 'TB', 'TBU',
1214 'HSRR0', 'HSRR1', 'HSPRG0', 'HSPRG1',
1215 }
1216 spr_csv = []
1217 for row in get_csv("sprs.csv"):
1218 if full_file or row['SPR'] in short_list:
1219 spr_csv.append(row)
1220
1221 spr_info = namedtuple('spr_info', 'SPR priv_mtspr priv_mfspr length idx')
1222 spr_dict = {}
1223 spr_byname = {}
1224 for row in spr_csv:
1225 info = spr_info(SPR=row['SPR'], priv_mtspr=row['priv_mtspr'],
1226 priv_mfspr=row['priv_mfspr'], length=int(row['len']),
1227 idx=int(row['Idx']))
1228 spr_dict[int(row['Idx'])] = info
1229 spr_byname[row['SPR']] = info
1230 fields = [(row['SPR'], int(row['Idx'])) for row in spr_csv]
1231 SPR = Enum('SPR', fields)
1232 return SPR, spr_dict, spr_byname
1233
1234
1235 SPRfull, spr_dict, spr_byname = get_spr_enum(full_file=True)
1236 SPRreduced, _, _ = get_spr_enum(full_file=False)
1237
1238 XER_bits = {
1239 'SO': 32,
1240 'OV': 33,
1241 'CA': 34,
1242 'OV32': 44,
1243 'CA32': 45
1244 }
1245
1246 MSRSpec = namedtuple("MSRSpec", ["dr", "pr", "sf"])
1247
1248 # flags for bfp_* functions
1249 BFP_FLAG_NAMES = (
1250 'vxsnan_flag',
1251 'vximz_flag',
1252 'vxidi_flag',
1253 'vxisi_flag',
1254 'vxzdz_flag',
1255 'vxsqrt_flag',
1256 'vxcvi_flag',
1257 'vxvc_flag',
1258 'ox_flag',
1259 'ux_flag',
1260 'xx_flag',
1261 'zx_flag',
1262 'inc_flag',
1263 )
1264
1265
1266 @unique
1267 class FMinMaxMode(Enum):
1268 """ FMM field for fminmax instruction.
1269 enumerant names match assembly aliases.
1270 """
1271 fminnum08 = 0b0000
1272 fmin19 = 0b0001
1273 fminnum19 = 0b0010
1274 fminc = 0b0011
1275 fminmagnum08 = 0b0100
1276 fminmag19 = 0b0101
1277 fminmagnum19 = 0b0110
1278 fminmagc = 0b0111
1279 fmaxnum08 = 0b1000
1280 fmax19 = 0b1001
1281 fmaxnum19 = 0b1010
1282 fmaxc = 0b1011
1283 fmaxmagnum08 = 0b1100
1284 fmaxmag19 = 0b1101
1285 fmaxmagnum19 = 0b1110
1286 fmaxmagc = 0b1111
1287
1288 if __name__ == '__main__':
1289 # find out what the heck is in SPR enum :)
1290 print("sprs full", len(SPRfull))
1291 print(dir(SPRfull))
1292 print("sprs reduced", len(SPRreduced))
1293 print(dir(SPRreduced))
1294 print(dir(Enum))
1295 print(SPRfull.__members__['TAR'])
1296 for x in SPRfull:
1297 print("full", x, x.value, str(x), x.name)
1298 for x in SPRreduced:
1299 print("reduced", x, x.value, str(x), x.name)
1300
1301 print("function", Function.ALU.name)