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