7d5ce4af07e8b629b1a20cc50fa1dbd63fd0dc58
[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", # binary bitmanip
753 "crternlogi", # ternary bitmanip
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
976
977 class SelType(Enum):
978 NONE = None
979 SRC = 's'
980 DST = 'd'
981
982 def __str__(self):
983 return {
984 SelType.NONE: "NONE",
985 SelType.SRC: "SRC",
986 SelType.DST: "DST",
987 }[self]
988
989
990 class In1Sel(Enum):
991 NONE = 0
992 RA = 1
993 RA_OR_ZERO = 2
994 SPR = 3
995 RS = 4 # for some ALU/Logical operations
996 RSp = RS
997 FRA = 5
998 FRAp = FRA
999 FRS = 6
1000 FRSp = FRS
1001 FRT = 7
1002 CIA = 8 # for addpcis
1003 RT = 9
1004
1005 def __str__(self):
1006 if self is In1Sel.RA_OR_ZERO:
1007 return "RA0"
1008 return self.name
1009
1010 @property
1011 def type(self):
1012 if self is In1Sel.NONE:
1013 return SelType.NONE
1014 return SelType.SRC
1015
1016
1017 class In2Sel(Enum):
1018 NONE = 0
1019 RB = 1
1020 CONST_UI = 2
1021 CONST_SI = 3
1022 CONST_UI_HI = 4
1023 CONST_SI_HI = 5
1024 CONST_LI = 6
1025 CONST_BD = 7
1026 CONST_DS = 8
1027 CONST_M1 = 9
1028 CONST_SH = 10
1029 CONST_SH32 = 11
1030 SPR = 12
1031 RS = 13 # for shiftrot (M-Form)
1032 RSp = RS
1033 FRB = 14
1034 FRBp = FRB
1035 CONST_SVD = 15 # for SVD-Form
1036 CONST_SVDS = 16 # for SVDS-Form
1037 # 17 available
1038 CONST_DXHI4 = 18 # for addpcis
1039 CONST_DQ = 19 # for ld/st-quad
1040
1041 def __str__(self):
1042 return self.name
1043
1044 @property
1045 def type(self):
1046 if self is In2Sel.NONE:
1047 return SelType.NONE
1048 return SelType.SRC
1049
1050
1051 class In3Sel(Enum):
1052 NONE = 0
1053 RS = 1
1054 RSp = RS
1055 RB = 2 # for shiftrot (M-Form)
1056 FRS = 3
1057 FRSp = FRS
1058 FRC = 4
1059 RC = 5 # for SVP64 bit-reverse LD/ST
1060 RT = 6 # for ternlog[i]
1061 RTp = RT
1062 FRA = 7
1063
1064 def __str__(self):
1065 return self.name
1066
1067 @property
1068 def type(self):
1069 if self is In3Sel.NONE:
1070 return SelType.NONE
1071 return SelType.SRC
1072
1073
1074 class OutSel(Enum):
1075 NONE = 0
1076 RT = 1
1077 RTp = RT
1078 RA = 2
1079 SPR = 3
1080 RT_OR_ZERO = 4
1081 FRT = 5
1082 FRTp = FRT
1083 FRS = 6
1084 FRSp = FRS
1085 RS = 7
1086 RSp = RS
1087 FRA = 8
1088
1089 def __str__(self):
1090 if self is OutSel.RT_OR_ZERO:
1091 return "RT0"
1092 return self.name
1093
1094 @property
1095 def type(self):
1096 if self is OutSel.NONE:
1097 return SelType.NONE
1098 return SelType.DST
1099
1100
1101 @unique
1102 class LDSTLen(Enum):
1103 NONE = 0
1104 is1B = 1
1105 is2B = 2
1106 is4B = 4
1107 is8B = 8
1108
1109 # Backward compatibility
1110 LdstLen = LDSTLen
1111
1112
1113 @unique
1114 class LDSTMode(Enum):
1115 NONE = 0
1116 update = 1
1117 cix = 2
1118 cx = 3
1119
1120
1121 @unique
1122 class RCOE(Enum):
1123 NONE = 0
1124 ONE = 1
1125 RC = 2 # includes OE
1126 RC_ONLY = 3 # does not include OE
1127
1128
1129 @unique
1130 class CryIn(Enum):
1131 ZERO = 0
1132 ONE = 1
1133 CA = 2
1134 OV = 3
1135
1136
1137 @unique
1138 class CRInSel(Enum):
1139 NONE = 0
1140 CR0 = 1
1141 BI = 2
1142 BFA = 3
1143 BA_BB = 4
1144 BC = 5
1145 WHOLE_REG = 6
1146 CR1 = 7
1147 BA = 8
1148 BFA_BFB_BF = 9
1149
1150 def __str__(self):
1151 return self.name
1152
1153 @property
1154 def type(self):
1155 if self is CRInSel.NONE:
1156 return SelType.NONE
1157 return SelType.SRC
1158
1159
1160 @unique
1161 class CRIn2Sel(Enum):
1162 NONE = 0
1163 BB = 1
1164 BFB = 2
1165
1166 def __str__(self):
1167 return self.name
1168
1169 @property
1170 def type(self):
1171 if self is CRIn2Sel.NONE:
1172 return SelType.NONE
1173 return SelType.SRC
1174
1175
1176 @unique
1177 class CROutSel(Enum):
1178 NONE = 0
1179 CR0 = 1
1180 BF = 2
1181 BT = 3
1182 WHOLE_REG = 4
1183 CR1 = 5
1184
1185 def __str__(self):
1186 return self.name
1187
1188 @property
1189 def type(self):
1190 if self is CROutSel.NONE:
1191 return SelType.NONE
1192 return SelType.DST
1193
1194
1195 # SPRs - Special-Purpose Registers. See V3.0B Figure 18 p971 and
1196 # http://libre-riscv.org/openpower/isatables/sprs.csv
1197 # http://bugs.libre-riscv.org/show_bug.cgi?id=261
1198 # http://bugs.libre-riscv.org/show_bug.cgi?id=859 - KAIVB
1199
1200 def get_spr_enum(full_file):
1201 """get_spr_enum - creates an Enum of SPRs, dynamically
1202 has the option to reduce the enum to a much shorter list.
1203 this saves drastically on the size of the regfile
1204 """
1205 short_list = {'PIDR', 'DAR', 'PRTBL', 'DSISR', 'SVSRR0', 'SVSTATE',
1206 'SVSTATE0', 'SVSTATE1', 'SVSTATE2', 'SVSTATE3',
1207 'SPRG0_priv', 'SPRG1_priv', 'SPRG2_priv', 'SPRG3_priv',
1208 'SPRG0', 'SPRG1', 'SPRG2', 'SPRG3', 'KAIVB',
1209 # hmmm should not be including these, they are FAST regs
1210 'CTR', 'LR', 'TAR', 'SRR0', 'SRR1', 'XER', 'DEC', 'TB', 'TBU',
1211 'HSRR0', 'HSRR1', 'HSPRG0', 'HSPRG1',
1212 }
1213 spr_csv = []
1214 for row in get_csv("sprs.csv"):
1215 if full_file or row['SPR'] in short_list:
1216 spr_csv.append(row)
1217
1218 spr_info = namedtuple('spr_info', 'SPR priv_mtspr priv_mfspr length idx')
1219 spr_dict = {}
1220 spr_byname = {}
1221 for row in spr_csv:
1222 info = spr_info(SPR=row['SPR'], priv_mtspr=row['priv_mtspr'],
1223 priv_mfspr=row['priv_mfspr'], length=int(row['len']),
1224 idx=int(row['Idx']))
1225 spr_dict[int(row['Idx'])] = info
1226 spr_byname[row['SPR']] = info
1227 fields = [(row['SPR'], int(row['Idx'])) for row in spr_csv]
1228 SPR = Enum('SPR', fields)
1229 return SPR, spr_dict, spr_byname
1230
1231
1232 SPRfull, spr_dict, spr_byname = get_spr_enum(full_file=True)
1233 SPRreduced, _, _ = get_spr_enum(full_file=False)
1234
1235 XER_bits = {
1236 'SO': 32,
1237 'OV': 33,
1238 'CA': 34,
1239 'OV32': 44,
1240 'CA32': 45
1241 }
1242
1243 MSRSpec = namedtuple("MSRSpec", ["dr", "pr", "sf"])
1244
1245 # flags for bfp_* functions
1246 BFP_FLAG_NAMES = (
1247 'vxsnan_flag',
1248 'vximz_flag',
1249 'vxidi_flag',
1250 'vxisi_flag',
1251 'vxzdz_flag',
1252 'vxsqrt_flag',
1253 'vxcvi_flag',
1254 'vxvc_flag',
1255 'ox_flag',
1256 'ux_flag',
1257 'xx_flag',
1258 'zx_flag',
1259 'inc_flag',
1260 )
1261
1262
1263 @unique
1264 class FMinMaxMode(Enum):
1265 """ FMM field for fminmax instruction.
1266 enumerant names match assembly aliases.
1267 """
1268 fminnum08 = 0b0000
1269 fmin19 = 0b0001
1270 fminnum19 = 0b0010
1271 fminc = 0b0011
1272 fminmagnum08 = 0b0100
1273 fminmag19 = 0b0101
1274 fminmagnum19 = 0b0110
1275 fminmagc = 0b0111
1276 fmaxnum08 = 0b1000
1277 fmax19 = 0b1001
1278 fmaxnum19 = 0b1010
1279 fmaxc = 0b1011
1280 fmaxmagnum08 = 0b1100
1281 fmaxmag19 = 0b1101
1282 fmaxmagnum19 = 0b1110
1283 fmaxmagc = 0b1111
1284
1285 if __name__ == '__main__':
1286 # find out what the heck is in SPR enum :)
1287 print("sprs full", len(SPRfull))
1288 print(dir(SPRfull))
1289 print("sprs reduced", len(SPRreduced))
1290 print(dir(SPRreduced))
1291 print(dir(Enum))
1292 print(SPRfull.__members__['TAR'])
1293 for x in SPRfull:
1294 print("full", x, x.value, str(x), x.name)
1295 for x in SPRreduced:
1296 print("reduced", x, x.value, str(x), x.name)
1297
1298 print("function", Function.ALU.name)