c0c1ddcacdb8bb48762caf9e460fb090cc63c40e
[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 "gbbd", # bitmanip - (aka bmatflip)
771 "cffpr", "cffpro",
772 "mffpr", "mffprs",
773 "ctfpr", "ctfprs",
774 "mtfpr", "mtfprs",
775 "hrfid", "icbi", "icbt", "isel", "isync",
776 "lbarx", "lbz", "lbzcix", "lbzu", "lbzux", "lbzx", # load byte
777 "ld", "ldarx", "ldbrx", "ldu", "ldux", "ldx", # load double
778 # "lbzbr", "lbzubr", # load byte SVP64 bit-reversed
779 # "ldbr", "ldubr", # load double SVP64 bit-reversed
780 "lfs", "lfsx", "lfsu", "lfsux", # FP load single
781 "lfd", "lfdx", "lfdu", "lfdux", "lfiwzx", "lfiwax", # FP load double
782 "lha", "lharx", "lhau", "lhaux", "lhax", # load half
783 "lhbrx", "lhz", "lhzu", "lhzux", "lhzx", # more load half
784 # "lhabr", "lhaubr", # load half SVP64 bit-reversed
785 # "lhzbr", "lhzubr", # more load half SVP64 bit-reversed
786 "lwa", "lwarx", "lwaux", "lwax", "lwbrx", # load word
787 "lwz", "lwzcix", "lwzu", "lwzux", "lwzx", # more load word
788 # "lwabr", # load word SVP64 bit-reversed
789 # "lwzbr", "lwzubr", # more load word SVP64 bit-reversed
790 "maddedu", "maddedus",
791 "maddhd", "maddhdu", "maddld", # INT multiply-and-add
792 "maddsubrs", # Int DCT Butterfly Add Sub and Round Shift
793 "maddrs", # Int DCT Butterfly Add and Accumulate and Round Shift
794 "msubrs", # Int DCT Butterfly Subtract from and Round Shift
795 "mcrf", "mcrxr", "mcrxrx", "mfcr/mfocrf", # CR mvs
796 "mfmsr", "mfspr",
797 "minmax", # AV bitmanip
798 "modsd", "modsw", "modud", "moduw",
799 "mtcrf/mtocrf", "mtmsr", "mtmsrd", "mtspr",
800 "mulhd", "mulhdu", "mulhw", "mulhwu", "mulld", "mulldo",
801 "mulli", "mullw", "mullwo",
802 "nand", "neg", "nego",
803 "nop",
804 "nor", "or", "orc", "ori", "oris",
805 "pcdec",
806 "pdepd", "pextd",
807 "popcntb", "popcntd", "popcntw",
808 "prtyd", "prtyw",
809 "rfid",
810 "rldcl", "rldcr", "rldic", "rldicl", "rldicr", "rldimi",
811 "rlwimi", "rlwinm", "rlwnm",
812 "setb",
813 "setbc", "setbcr", "setnbc", "setnbcr",
814 "setvl", # https://libre-soc.org/openpower/sv/setvl
815 "sc", "scv",
816 "svindex", # https://libre-soc.org/openpower/sv/remap
817 "svremap", # https://libre-soc.org/openpower/sv/remap - TEMPORARY
818 "svshape", # https://libre-soc.org/openpower/sv/remap/#svshape
819 "svshape2", # https://libre-soc.org/openpower/sv/remap/discussion TODO
820 "svstep", # https://libre-soc.org/openpower/sv/setvl
821 "sim_cfg",
822 "sadd", "saddw", "sadduw",
823 "slbia", "sld", "slw", "srad", "sradi",
824 "sraw", "srawi", "srd", "srw",
825 "stb", "stbcix", "stbcx", "stbu", "stbux", "stbx",
826 "std", "stdbrx", "stdcx", "stdu", "stdux", "stdx",
827 "stfs", "stfsx", "stfsu", "stfux", "stfsux", # FP store single
828 "stfd", "stfdx", "stfdu", "stfdux", "stfiwx", # FP store double
829 "sth", "sthbrx", "sthcx", "sthu", "sthux", "sthx",
830 "stw", "stwbrx", "stwcx", "stwu", "stwux", "stwx",
831 "subf", "subfc", "subfco", "subfe", "subfeo", "subfic",
832 "subfme", "subfmeo", "subfo", "subfze", "subfzeo",
833 "sync",
834 "ternlogi",
835 "td", "tdi",
836 "tlbie", "tlbiel", "tlbsync",
837 "tw", "twi",
838 "wait",
839 "xor", "xori", "xoris",
840 *FPTRANS_INSNS,
841 ]
842
843 # two-way lookup of instruction-to-index and vice-versa
844 insns = {}
845 asmidx = {}
846 for i, insn in enumerate(_insns):
847 insns[i] = insn
848 asmidx[insn] = i
849
850 # must be long enough to cover all instructions
851 asmlen = len(_insns).bit_length()
852
853 # Internal Operation numbering. Add new opcodes here (FPADD, FPMUL etc.)
854
855
856 @unique
857 class MicrOp(Enum):
858 OP_ILLEGAL = 0 # important that this is zero (see power_decoder.py)
859 OP_NOP = 1
860 OP_ADD = 2
861 OP_ADDPCIS = 3
862 OP_AND = 4
863 OP_ATTN = 5
864 OP_B = 6
865 OP_BC = 7
866 OP_BCREG = 8
867 OP_BPERM = 9
868 OP_CMP = 10
869 OP_CMPB = 11
870 OP_CMPEQB = 12
871 OP_CMPRB = 13
872 OP_CNTZ = 14
873 OP_CRAND = 15
874 OP_CRANDC = 16
875 OP_CREQV = 17
876 OP_CRNAND = 18
877 OP_CRNOR = 19
878 OP_CROR = 20
879 OP_CRORC = 21
880 OP_CRXOR = 22
881 OP_DARN = 23
882 OP_DCBF = 24
883 OP_DCBST = 25
884 OP_DCBT = 26
885 OP_DCBTST = 27
886 OP_DCBZ = 28
887 OP_DIV = 29
888 OP_DIVE = 30
889 OP_EXTS = 31
890 OP_EXTSWSLI = 32
891 OP_ICBI = 33
892 OP_ICBT = 34
893 OP_ISEL = 35
894 OP_ISYNC = 36
895 OP_LOAD = 37
896 OP_STORE = 38
897 OP_MADDHD = 39
898 OP_MADDHDU = 40
899 OP_MADDLD = 41
900 OP_MCRF = 42
901 OP_MCRXR = 43
902 OP_MCRXRX = 44
903 OP_MFCR = 45
904 OP_MFSPR = 46
905 OP_MOD = 47
906 OP_MTCRF = 48
907 OP_MTSPR = 49
908 OP_MUL_L64 = 50
909 OP_MUL_H64 = 51
910 OP_MUL_H32 = 52
911 OP_OR = 53
912 OP_POPCNT = 54
913 OP_PRTY = 55
914 OP_RLC = 56
915 OP_RLCL = 57
916 OP_RLCR = 58
917 OP_SETB = 59
918 OP_SHL = 60
919 OP_SHR = 61
920 OP_SYNC = 62
921 OP_TRAP = 63
922 OP_XOR = 67
923 OP_SIM_CONFIG = 68
924 OP_CROP = 69
925 OP_RFID = 70
926 OP_MFMSR = 71
927 OP_MTMSRD = 72
928 OP_SC = 73
929 OP_MTMSR = 74
930 OP_TLBIE = 75
931 OP_SETVL = 76
932 OP_FPOP = 77 # temporary: replace with actual ops
933 OP_FPOP_I = 78 # temporary: replace with actual ops
934 OP_FP_MADD = 79
935 OP_SVREMAP = 80
936 OP_SVSHAPE = 81
937 OP_SVSTEP = 82
938 OP_ADDG6S = 83
939 OP_CDTBCD = 84
940 OP_CBCDTD = 85
941 OP_TERNLOG = 86
942 OP_FETCH_FAILED = 87
943 # 88 available
944 OP_MINMAX = 89
945 OP_AVGADD = 90
946 OP_ABSDIFF = 91
947 OP_ABSADD = 92
948 OP_CPROP = 93
949 OP_BMASK = 94
950 OP_SVINDEX = 95
951 OP_FMVIS = 96
952 OP_FISHMV = 97
953 OP_PCDEC = 98
954 OP_MADDEDU = 99
955 OP_DIVMOD2DU = 100
956 OP_DSHL = 101
957 OP_DSHR = 102
958 OP_SHADD = 103
959 OP_MADDSUBRS = 104
960 OP_MADDRS = 105
961 OP_MSUBRS = 106
962 OP_BYTEREV = 107
963 OP_CFUGE = 108
964 OP_PDEP = 109
965 OP_PEXT = 110
966 OP_SETBC = 111
967 OP_BMAT = 112 # bmatflip/xor/and - known by many names (vgbbd in Power)
968
969
970 class SelType(Enum):
971 NONE = None
972 SRC = 's'
973 DST = 'd'
974
975 def __str__(self):
976 return {
977 SelType.NONE: "NONE",
978 SelType.SRC: "SRC",
979 SelType.DST: "DST",
980 }[self]
981
982
983 class In1Sel(Enum):
984 NONE = 0
985 RA = 1
986 RA_OR_ZERO = 2
987 SPR = 3
988 RS = 4 # for some ALU/Logical operations
989 RSp = RS
990 FRA = 5
991 FRAp = FRA
992 FRS = 6
993 FRSp = FRS
994 FRT = 7
995 CIA = 8 # for addpcis
996 RT = 9
997
998 def __str__(self):
999 if self is In1Sel.RA_OR_ZERO:
1000 return "RA0"
1001 return self.name
1002
1003 @property
1004 def type(self):
1005 if self is In1Sel.NONE:
1006 return SelType.NONE
1007 return SelType.SRC
1008
1009
1010 class In2Sel(Enum):
1011 NONE = 0
1012 RB = 1
1013 CONST_UI = 2
1014 CONST_SI = 3
1015 CONST_UI_HI = 4
1016 CONST_SI_HI = 5
1017 CONST_LI = 6
1018 CONST_BD = 7
1019 CONST_DS = 8
1020 CONST_M1 = 9
1021 CONST_SH = 10
1022 CONST_SH32 = 11
1023 SPR = 12
1024 RS = 13 # for shiftrot (M-Form)
1025 RSp = RS
1026 FRB = 14
1027 FRBp = FRB
1028 CONST_SVD = 15 # for SVD-Form
1029 CONST_SVDS = 16 # for SVDS-Form
1030 # 17 available
1031 CONST_DXHI4 = 18 # for addpcis
1032 CONST_DQ = 19 # for ld/st-quad
1033
1034 def __str__(self):
1035 return self.name
1036
1037 @property
1038 def type(self):
1039 if self is In2Sel.NONE:
1040 return SelType.NONE
1041 return SelType.SRC
1042
1043
1044 class In3Sel(Enum):
1045 NONE = 0
1046 RS = 1
1047 RSp = RS
1048 RB = 2 # for shiftrot (M-Form)
1049 FRS = 3
1050 FRSp = FRS
1051 FRC = 4
1052 RC = 5 # for SVP64 bit-reverse LD/ST
1053 RT = 6 # for ternlog[i]
1054 RTp = RT
1055 FRA = 7
1056
1057 def __str__(self):
1058 return self.name
1059
1060 @property
1061 def type(self):
1062 if self is In3Sel.NONE:
1063 return SelType.NONE
1064 return SelType.SRC
1065
1066
1067 class OutSel(Enum):
1068 NONE = 0
1069 RT = 1
1070 RTp = RT
1071 RA = 2
1072 SPR = 3
1073 RT_OR_ZERO = 4
1074 FRT = 5
1075 FRTp = FRT
1076 FRS = 6
1077 FRSp = FRS
1078 RS = 7
1079 RSp = RS
1080 FRA = 8
1081
1082 def __str__(self):
1083 if self is OutSel.RT_OR_ZERO:
1084 return "RT0"
1085 return self.name
1086
1087 @property
1088 def type(self):
1089 if self is OutSel.NONE:
1090 return SelType.NONE
1091 return SelType.DST
1092
1093
1094 @unique
1095 class LDSTLen(Enum):
1096 NONE = 0
1097 is1B = 1
1098 is2B = 2
1099 is4B = 4
1100 is8B = 8
1101
1102 # Backward compatibility
1103 LdstLen = LDSTLen
1104
1105
1106 @unique
1107 class LDSTMode(Enum):
1108 NONE = 0
1109 update = 1
1110 cix = 2
1111 cx = 3
1112
1113
1114 @unique
1115 class RCOE(Enum):
1116 NONE = 0
1117 ONE = 1
1118 RC = 2 # includes OE
1119 RC_ONLY = 3 # does not include OE
1120
1121
1122 @unique
1123 class CryIn(Enum):
1124 ZERO = 0
1125 ONE = 1
1126 CA = 2
1127 OV = 3
1128
1129
1130 @unique
1131 class CRInSel(Enum):
1132 NONE = 0
1133 CR0 = 1
1134 BI = 2
1135 BFA = 3
1136 BA_BB = 4
1137 BC = 5
1138 WHOLE_REG = 6
1139 CR1 = 7
1140 BA = 8
1141
1142 def __str__(self):
1143 return self.name
1144
1145 @property
1146 def type(self):
1147 if self is CRInSel.NONE:
1148 return SelType.NONE
1149 return SelType.SRC
1150
1151
1152 @unique
1153 class CRIn2Sel(Enum):
1154 NONE = 0
1155 BB = 1
1156
1157 def __str__(self):
1158 return self.name
1159
1160 @property
1161 def type(self):
1162 if self is CRIn2Sel.NONE:
1163 return SelType.NONE
1164 return SelType.SRC
1165
1166
1167 @unique
1168 class CROutSel(Enum):
1169 NONE = 0
1170 CR0 = 1
1171 BF = 2
1172 BT = 3
1173 WHOLE_REG = 4
1174 CR1 = 5
1175
1176 def __str__(self):
1177 return self.name
1178
1179 @property
1180 def type(self):
1181 if self is CROutSel.NONE:
1182 return SelType.NONE
1183 return SelType.DST
1184
1185
1186 # SPRs - Special-Purpose Registers. See V3.0B Figure 18 p971 and
1187 # http://libre-riscv.org/openpower/isatables/sprs.csv
1188 # http://bugs.libre-riscv.org/show_bug.cgi?id=261
1189 # http://bugs.libre-riscv.org/show_bug.cgi?id=859 - KAIVB
1190
1191 def get_spr_enum(full_file):
1192 """get_spr_enum - creates an Enum of SPRs, dynamically
1193 has the option to reduce the enum to a much shorter list.
1194 this saves drastically on the size of the regfile
1195 """
1196 short_list = {'PIDR', 'DAR', 'PRTBL', 'DSISR', 'SVSRR0', 'SVSTATE',
1197 'SVSTATE0', 'SVSTATE1', 'SVSTATE2', 'SVSTATE3',
1198 'SPRG0_priv', 'SPRG1_priv', 'SPRG2_priv', 'SPRG3_priv',
1199 'SPRG0', 'SPRG1', 'SPRG2', 'SPRG3', 'KAIVB',
1200 # hmmm should not be including these, they are FAST regs
1201 'CTR', 'LR', 'TAR', 'SRR0', 'SRR1', 'XER', 'DEC', 'TB', 'TBU',
1202 'HSRR0', 'HSRR1', 'HSPRG0', 'HSPRG1',
1203 }
1204 spr_csv = []
1205 for row in get_csv("sprs.csv"):
1206 if full_file or row['SPR'] in short_list:
1207 spr_csv.append(row)
1208
1209 spr_info = namedtuple('spr_info', 'SPR priv_mtspr priv_mfspr length idx')
1210 spr_dict = {}
1211 spr_byname = {}
1212 for row in spr_csv:
1213 info = spr_info(SPR=row['SPR'], priv_mtspr=row['priv_mtspr'],
1214 priv_mfspr=row['priv_mfspr'], length=int(row['len']),
1215 idx=int(row['Idx']))
1216 spr_dict[int(row['Idx'])] = info
1217 spr_byname[row['SPR']] = info
1218 fields = [(row['SPR'], int(row['Idx'])) for row in spr_csv]
1219 SPR = Enum('SPR', fields)
1220 return SPR, spr_dict, spr_byname
1221
1222
1223 SPRfull, spr_dict, spr_byname = get_spr_enum(full_file=True)
1224 SPRreduced, _, _ = get_spr_enum(full_file=False)
1225
1226 XER_bits = {
1227 'SO': 32,
1228 'OV': 33,
1229 'CA': 34,
1230 'OV32': 44,
1231 'CA32': 45
1232 }
1233
1234 MSRSpec = namedtuple("MSRSpec", ["dr", "pr", "sf"])
1235
1236 # flags for bfp_* functions
1237 BFP_FLAG_NAMES = (
1238 'vxsnan_flag',
1239 'vximz_flag',
1240 'vxidi_flag',
1241 'vxisi_flag',
1242 'vxzdz_flag',
1243 'vxsqrt_flag',
1244 'vxcvi_flag',
1245 'vxvc_flag',
1246 'ox_flag',
1247 'ux_flag',
1248 'xx_flag',
1249 'zx_flag',
1250 'inc_flag',
1251 )
1252
1253
1254 @unique
1255 class FMinMaxMode(Enum):
1256 """ FMM field for fminmax instruction.
1257 enumerant names match assembly aliases.
1258 """
1259 fminnum08 = 0b0000
1260 fmin19 = 0b0001
1261 fminnum19 = 0b0010
1262 fminc = 0b0011
1263 fminmagnum08 = 0b0100
1264 fminmag19 = 0b0101
1265 fminmagnum19 = 0b0110
1266 fminmagc = 0b0111
1267 fmaxnum08 = 0b1000
1268 fmax19 = 0b1001
1269 fmaxnum19 = 0b1010
1270 fmaxc = 0b1011
1271 fmaxmagnum08 = 0b1100
1272 fmaxmag19 = 0b1101
1273 fmaxmagnum19 = 0b1110
1274 fmaxmagc = 0b1111
1275
1276 if __name__ == '__main__':
1277 # find out what the heck is in SPR enum :)
1278 print("sprs full", len(SPRfull))
1279 print(dir(SPRfull))
1280 print("sprs reduced", len(SPRreduced))
1281 print(dir(SPRreduced))
1282 print(dir(Enum))
1283 print(SPRfull.__members__['TAR'])
1284 for x in SPRfull:
1285 print("full", x, x.value, str(x), x.name)
1286 for x in SPRreduced:
1287 print("reduced", x, x.value, str(x), x.name)
1288
1289 print("function", Function.ALU.name)