rename "none" __repr__ to "NONE" in SVExtra and SelType
[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 """gets a not-entirely-csv-file-formatted database, which allows comments
44 """
45 file_path = find_wiki_file(name)
46 with open(file_path, 'r') as csvfile:
47 csvfile = filter(lambda row: row[0] !='#', csvfile) # strip "#..."
48 reader = csv.DictReader(csvfile)
49 return list(reader)
50
51
52 # names of the fields in the tables that don't correspond to an enum
53 single_bit_flags = ['inv A', 'inv out',
54 'cry out', 'BR', 'sgn ext', 'rsrv', '32b',
55 'sgn', 'lk', 'sgl pipe']
56
57 # default values for fields in the table
58 default_values = {'unit': "NONE", 'internal op': "OP_ILLEGAL",
59 'in1': "RA", 'in2': 'NONE', 'in3': 'NONE', 'out': 'NONE',
60 'CR in': 'NONE',
61 'ldst len': 'NONE',
62 'upd': '0',
63 'rc': 'NONE', 'cry in': 'ZERO', 'form': 'NONE'}
64
65
66 def get_signal_name(name):
67 if name[0].isdigit():
68 name = "is_" + name
69 return name.lower().replace(' ', '_')
70
71
72 class Enum(_Enum):
73 @classmethod
74 def _missing_(cls, desc):
75 if isinstance(desc, str):
76 try:
77 if desc == "":
78 desc = 0
79 else:
80 desc = int(desc, 0)
81 except ValueError:
82 pass
83 keys = {item.name:item for item in cls}
84 descs = {item.value:item for item in cls}
85 return keys.get(desc, descs.get(desc))
86
87
88 # this corresponds to which Function Unit (pipeline-with-Reservation-Stations)
89 # is to process and guard the operation. they are roughly divided by having
90 # the same register input/output signature (X-Form, etc.)
91
92
93 @unique
94 class Function(Enum):
95 NONE = 0
96 ALU = 1 << 1
97 LDST = 1 << 2
98 SHIFT_ROT = 1 << 3
99 LOGICAL = 1 << 4
100 BRANCH = 1 << 5
101 CR = 1 << 6
102 TRAP = 1 << 7
103 MUL = 1 << 8
104 DIV = 1 << 9
105 SPR = 1 << 10
106 MMU = 1 << 11
107 SV = 1 << 12 # Simple-V https://libre-soc.org/openpower/sv
108 VL = 1 << 13 # setvl
109 FPU = 1 << 14 # FPU
110
111 @functools.lru_cache(maxsize=None)
112 def __repr__(self):
113 counter = 0
114 value = int(self.value)
115 if value != 0:
116 while value != 0:
117 counter += 1
118 value >>= 1
119 counter -= 1
120 desc = f"(1 << {counter})"
121 else:
122 desc = "0"
123 return f"<{self.__class__.__name__}.{self.name}: {desc}>"
124
125
126 @unique
127 class Form(Enum):
128 NONE = 0
129 I = 1
130 B = 2
131 SC = 3
132 D = 4
133 DS = 5
134 DQ = 6
135 DX = 7
136 X = 8
137 XL = 9
138 XFX = 10
139 XFL = 11
140 XX1 = 12
141 XX2 = 13
142 XX3 = 14
143 XX4 = 15
144 XS = 16
145 XO = 17
146 A = 18
147 M = 19
148 MD = 20
149 MDS = 21
150 VA = 22
151 VC = 23
152 VX = 24
153 EVX = 25
154 EVS = 26
155 Z22 = 27
156 Z23 = 28
157 SVL = 29 # Simple-V for setvl instruction
158 SVD = 30 # Simple-V for LD/ST bit-reverse, variant of D-Form
159 SVDS = 31 # Simple-V for LD/ST bit-reverse, variant of DS-Form
160 SVM = 32 # Simple-V SHAPE mode
161 SVM2 = 33 # Simple-V SHAPE2 mode - fits into SVM
162 SVRM = 34 # Simple-V REMAP mode
163 TLI = 35 # ternlogi
164 XB = 36
165 BM2 = 37 # bmask
166 SVI = 38 # Simple-V Index Mode
167 VA2 = 39
168 SVC = 40
169 SVR = 41
170 CRB = 42 # crternlogi / crbinlut
171 MM = 43 # [f]minmax[s][.]
172 CW = 44
173 CW2 = 45
174 DCT = 46 # fdmadds
175
176 # Simple-V svp64 fields https://libre-soc.org/openpower/sv/svp64/
177
178
179 class SVMode(Enum):
180 NONE = 0 # for non-SV instructions only
181 NORMAL = auto()
182 LDST_IDX = auto()
183 LDST_IMM = auto()
184 BRANCH = auto()
185 CROP = auto()
186
187
188 @unique
189 class SVPType(Enum):
190 NONE = 0
191 P1 = 1
192 P2 = 2
193 P2M = 3 # for mixed EXTRA3/3/2 where MASK_SRC is RM[6,7,18]
194
195 @classmethod
196 def _missing_(cls, desc):
197 return {"1P": SVPType.P1, "2P": SVPType.P2, "2PM": SVPType.P2M}.get(desc)
198
199 def __repr__(self):
200 return {
201 SVPType.NONE: "NONE",
202 SVPType.P1: "1P",
203 SVPType.P2: "2P",
204 SVPType.P2M: "2PM",
205 }[self]
206
207
208 @unique
209 class SVEType(Enum):
210 """SVEType
211 * EXTRA2 : 0: [10,11] 1: [12,13] 2: [14,15] 3: [16,17] unused: [18]
212 * EXTRA3 : 0: [10,11,12] 1: [13,14,15] mask: [16,17,18]
213 * EXTRA32: 0: [10,11,12] 1: [13,14,15] 2: [16,17] mask: [6,7,18]
214 """
215 NONE = 0
216 EXTRA2 = 1
217 EXTRA3 = 2
218 EXTRA32 = 3 # mixed EXTRA3 and EXTRA2 using RM bits 6&7 for MASK_SRC
219
220 def __repr__(self):
221 return self.name
222
223
224 @unique
225 class SVMaskSrc(Enum):
226 NO = 0
227 EN = 1
228
229 def __repr__(self):
230 return self.name
231
232
233 @unique
234 class SVExtra(Enum):
235 NONE = 0
236 Idx0 = 1
237 Idx1 = 2
238 Idx2 = 3
239 Idx3 = 4
240 Idx_1_2 = 5 # due to weird BA/BB for crops
241
242 def __repr__(self):
243 return {
244 SVExtra.NONE: "NONE",
245 SVExtra.Idx0: "extra0",
246 SVExtra.Idx1: "extra1",
247 SVExtra.Idx2: "extra2",
248 SVExtra.Idx3: "extra3",
249 SVExtra.Idx_1_2: "extra1/extra2",
250 }[self]
251
252 # Backward compatibility
253 SVEXTRA = SVExtra
254
255
256 class Reg(Enum):
257 NONE = auto()
258 RA = auto()
259 RA_OR_ZERO = RA
260 RB = auto()
261 RC = auto()
262 RS = auto()
263 RT = auto()
264 RT_OR_ZERO = RT
265 FRA = auto()
266 FRB = auto()
267 FRC = auto()
268 FRS = auto()
269 FRT = auto()
270 CR = auto()
271 CR0 = auto()
272 CR1 = auto()
273 BF = auto()
274 BFA = auto()
275 BA = auto()
276 BB = auto()
277 BC = auto()
278 BI = auto()
279 BT = auto()
280 BFT = auto()
281 WHOLE_REG = auto()
282 SPR = auto()
283 RSp = auto()
284 RTp = auto()
285 FRAp = auto()
286 FRBp = auto()
287 FRSp = auto()
288 FRTp = auto()
289
290 @classmethod
291 def _missing_(cls, desc):
292 selectors = (
293 In1Sel, In2Sel, In3Sel, CRInSel, CRIn2Sel,
294 OutSel, CROutSel,
295 )
296 if isinstance(desc, selectors):
297 return cls.__members__.get(desc.name)
298
299 return cls.__members__.get(desc)
300
301 @property
302 def alias(self):
303 alias = {
304 Reg.RSp: Reg.RS,
305 Reg.RTp: Reg.RT,
306 Reg.FRAp: Reg.FRA,
307 Reg.FRBp: Reg.FRB,
308 Reg.FRSp: Reg.FRS,
309 Reg.FRTp: Reg.FRT,
310 }.get(self)
311 if alias is not None:
312 return alias
313
314 alias = {
315 Reg.RA_OR_ZERO: Reg.RA,
316 Reg.RT_OR_ZERO: Reg.RT,
317 }.get(self)
318 if alias is not None:
319 return alias
320
321 return self
322
323 @property
324 def or_zero(self):
325 return (self in (
326 Reg.RA_OR_ZERO,
327 Reg.RT_OR_ZERO,
328 ))
329
330 @property
331 def pair(self):
332 return (self in (
333 Reg.RSp,
334 Reg.RTp,
335 Reg.FRAp,
336 Reg.FRBp,
337 Reg.FRSp,
338 Reg.FRTp,
339 ))
340
341
342 @unique
343 class SVP64PredMode(Enum):
344 ALWAYS = 0
345 INT = 1
346 CR = 2
347 RC1 = 3
348
349
350 @unique
351 class SVP64PredInt(Enum):
352 ALWAYS = 0b000
353 R3_UNARY = 0b001
354 R3 = 0b010
355 R3_N = 0b011
356 R10 = 0b100
357 R10_N = 0b101
358 R30 = 0b110
359 R30_N = 0b111
360
361 @classmethod
362 def _missing_(cls, desc):
363 if isinstance(desc, str):
364 value = desc
365 values = {
366 "^r3": cls.R3_UNARY,
367 "r3": cls.R3,
368 "~r3": cls.R3_N,
369 "r10": cls.R10,
370 "~r10": cls.R10_N,
371 "r30": cls.R30,
372 "~r30": cls.R30_N,
373 }
374 if value.startswith("~"):
375 value = f"~{value[1:].strip()}"
376 elif "<<" in value: # 1 << r3
377 (lhs, _, rhs) = value.partition("<<")
378 lhs = lhs.strip().lower()
379 rhs = rhs.strip().lower()
380 if (lhs == "1") and (rhs in ("r3", "%r3")):
381 value = "^r3"
382
383 return values.get(value)
384
385 return super()._missing_(desc)
386
387 def __str__(self):
388 return {
389 self.__class__.ALWAYS: "",
390 self.__class__.R3_UNARY: "^r3",
391 self.__class__.R3: "r3",
392 self.__class__.R3_N: "~r3",
393 self.__class__.R10: "r10",
394 self.__class__.R10_N: "~r10",
395 self.__class__.R30: "r30",
396 self.__class__.R30_N: "~r30",
397 }[self]
398
399 def __repr__(self):
400 return f"{self.__class__.__name__}({str(self)})"
401
402 def __int__(self):
403 return self.value
404
405 @property
406 def mode(self):
407 return SVP64PredMode.INT
408
409 @property
410 def inv(self):
411 return (self.value & 0b1)
412
413 @property
414 def state(self):
415 return (self.value >> 1)
416
417
418 class SVP64PredCR(Enum):
419 LT = 0
420 GE = 1
421 NL = GE
422 GT = 2
423 LE = 3
424 NG = LE
425 EQ = 4
426 NE = 5
427 SO = 6
428 UN = SO
429 NS = 7
430 NU = NS
431
432 @classmethod
433 def _missing_(cls, desc):
434 if isinstance(desc, str):
435 name = desc.upper()
436 return cls.__members__.get(name)
437
438 return super()._missing_(desc)
439
440 def __int__(self):
441 return self.value
442
443 @property
444 def mode(self):
445 return SVP64PredMode.CR
446
447 @property
448 def inv(self):
449 return (self.value & 0b1)
450
451 @property
452 def state(self):
453 return (self.value >> 1)
454
455
456 @unique
457 class SVP64PredRC1(Enum):
458 RC1 = 0
459 RC1_N = 1
460
461 @classmethod
462 def _missing_(cls, desc):
463 return {
464 "RC1": SVP64PredRC1.RC1,
465 "~RC1": SVP64PredRC1.RC1_N,
466 }.get(desc)
467
468 def __int__(self):
469 return 1
470
471 @property
472 def mode(self):
473 return SVP64PredMode.RC1
474
475 @property
476 def inv(self):
477 return (self is SVP64PredRC1.RC1_N)
478
479 @property
480 def state(self):
481 return 1
482
483
484 class SVP64Pred(Enum):
485 ALWAYS = SVP64PredInt.ALWAYS
486 R3_UNARY = SVP64PredInt.R3_UNARY
487 R3 = SVP64PredInt.R3
488 R3_N = SVP64PredInt.R3_N
489 R10 = SVP64PredInt.R10
490 R10_N = SVP64PredInt.R10_N
491 R30 = SVP64PredInt.R30
492 R30_N = SVP64PredInt.R30_N
493
494 LT = SVP64PredCR.LT
495 GE = SVP64PredCR.GE
496 GT = SVP64PredCR.GT
497 LE = SVP64PredCR.LE
498 EQ = SVP64PredCR.EQ
499 NE = SVP64PredCR.NE
500 SO = SVP64PredCR.SO
501 NS = SVP64PredCR.NS
502
503 RC1 = SVP64PredRC1.RC1
504 RC1_N = SVP64PredRC1.RC1_N
505
506 @classmethod
507 def _missing_(cls, desc):
508 if isinstance(desc, str):
509 values = {item.value:item for item in cls}
510 for subcls in (SVP64PredInt, SVP64PredCR, SVP64PredRC1):
511 try:
512 return values.get(subcls(desc))
513 except ValueError:
514 pass
515 return None
516
517 return super()._missing_(desc)
518
519 def __int__(self):
520 return int(self.value)
521
522 @property
523 def mode(self):
524 return self.value.mode
525
526 @property
527 def inv(self):
528 return self.value.inv
529
530 @property
531 def state(self):
532 return self.value.state
533
534
535 @unique
536 class SVP64RMMode(Enum):
537 NORMAL = 0
538 MAPREDUCE = 1
539 FFIRST = 2
540 SATURATE = 3
541 BRANCH = 5
542
543
544 @unique
545 class SVP64BCPredMode(Enum):
546 NONE = 0
547 MASKZERO = 1
548 MASKONE = 2
549
550
551 @unique
552 class SVP64BCVLSETMode(Enum):
553 NONE = 0
554 VL_INCL = 1
555 VL_EXCL = 2
556
557
558 # note that these are chosen to be exactly the same as
559 # SVP64 RM bit 4. ALL=1 => bit4=1
560 @unique
561 class SVP64BCGate(Enum):
562 ANY = 0
563 ALL = 1
564
565
566 class SVP64BCCTRMode(Enum):
567 NONE = 0
568 TEST = 1
569 TEST_INV = 2
570
571
572 @unique
573 class SVP64Width(Enum):
574 DEFAULT = 0
575 EW_32 = 1
576 EW_16 = 2
577 EW_8 = 3
578
579 @classmethod
580 def _missing_(cls, desc):
581 if isinstance(desc, str):
582 return {
583 "32": SVP64Width.EW_32,
584 "16": SVP64Width.EW_16,
585 "8": SVP64Width.EW_8,
586 }.get(desc)
587
588 return super()._missing_(desc)
589
590
591 @unique
592 class SVP64SubVL(Enum):
593 VEC1 = 0
594 VEC2 = 1
595 VEC3 = 2
596 VEC4 = 3
597
598 @classmethod
599 def _missing_(cls, desc):
600 if isinstance(desc, str):
601 name = desc.upper()
602 return cls.__members__.get(name)
603
604 return super()._missing_(desc)
605
606
607 @unique
608 class SVP64Sat(Enum):
609 NONE = 0
610 SIGNED = 1
611 UNSIGNED = 2
612
613
614 @unique
615 class SVP64LDSTmode(Enum):
616 NONE = 0
617 INDEXED = 1
618 ELSTRIDE = 2
619 UNITSTRIDE = 3
620
621
622 class RegType(Enum):
623 GPR = 0
624 RA = GPR
625 RB = GPR
626 RC = GPR
627 RS = GPR
628 RSp = RS
629 RT = GPR
630 RTp = RT
631
632 FPR = 1
633 FRA = FPR
634 FRAp = FRA
635 FRB = FPR
636 FRBp = FRB
637 FRC = FPR
638 FRS = FPR
639 FRSp = FRS
640 FRT = FPR
641 FRTp = FRT
642
643 CR_3BIT = 2 # CR field; the CR register is 32-bit
644 BF = CR_3BIT
645 BFA = CR_3BIT
646
647 CR_5BIT = 3 # bit of the 32-bit CR register
648 BA = CR_5BIT
649 BB = CR_5BIT
650 BC = CR_5BIT
651 BI = CR_5BIT
652 BT = CR_5BIT
653
654 XER_BIT = 4 # XER bits, includes OV, OV32, SO, CA, CA32
655 OV = XER_BIT
656 OV32 = XER_BIT
657 CA = XER_BIT
658 CA32 = XER_BIT
659 SO = XER_BIT
660
661 @classmethod
662 def _missing_(cls, value):
663 if isinstance(value, Reg):
664 return cls.__members__.get(value.name)
665
666 return super()._missing_(value)
667
668
669 FPTRANS_INSNS = (
670 "fatan2", "fatan2s",
671 "fatan2pi", "fatan2pis",
672 "fpow", "fpows",
673 "fpown", "fpowns",
674 "fpowr", "fpowrs",
675 "frootn", "frootns",
676 "fhypot", "fhypots",
677 "frsqrt", "frsqrts",
678 "fcbrt", "fcbrts",
679 "frecip", "frecips",
680 "fexp2m1", "fexp2m1s",
681 "flog2p1", "flog2p1s",
682 "fexp2", "fexp2s",
683 "flog2", "flog2s",
684 "fexpm1", "fexpm1s",
685 "flogp1", "flogp1s",
686 "fexp", "fexps",
687 "flog", "flogs",
688 "fexp10m1", "fexp10m1s",
689 "flog10p1", "flog10p1s",
690 "fexp10", "fexp10s",
691 "flog10", "flog10s",
692 "fsin", "fsins",
693 "fcos", "fcoss",
694 "ftan", "ftans",
695 "fasin", "fasins",
696 "facos", "facoss",
697 "fatan", "fatans",
698 "fsinpi", "fsinpis",
699 "fcospi", "fcospis",
700 "ftanpi", "ftanpis",
701 "fasinpi", "fasinpis",
702 "facospi", "facospis",
703 "fatanpi", "fatanpis",
704 "fsinh", "fsinhs",
705 "fcosh", "fcoshs",
706 "ftanh", "ftanhs",
707 "fasinh", "fasinhs",
708 "facosh", "facoshs",
709 "fatanh", "fatanhs",
710 # fmin*/fmax* need to be replaced with fminmax
711 # https://bugs.libre-soc.org/show_bug.cgi?id=1057
712 # commented for now to make space for fmv/cvt
713 # "fminnum08", "fminnum08s",
714 # "fmaxnum08", "fmaxnum08s",
715 # "fmin19", "fmin19s",
716 # "fmax19", "fmax19s",
717 # "fminnum19", "fminnum19s",
718 # "fmaxnum19", "fmaxnum19s",
719 # "fminc", "fmincs",
720 # "fmaxc", "fmaxcs",
721 # "fminmagnum08", "fminmagnum08s",
722 # "fmaxmagnum08", "fmaxmagnum08s",
723 # "fminmag19", "fminmag19s",
724 # "fmaxmag19", "fmaxmag19s",
725 # "fminmagnum19", "fminmagnum19s",
726 # "fmaxmagnum19", "fmaxmagnum19s",
727 # "fminmagc", "fminmagcs",
728 # "fmaxmagc", "fmaxmagcs",
729 "fmod", "fmods",
730 "fremainder", "fremainders",
731 )
732
733
734 # supported instructions: make sure to keep up-to-date with CSV files
735 # just like everything else
736 _insns = [
737 "NONE", "add", "addc", "addco", "adde", "addeo",
738 "addi", "addic", "addic.", "addis",
739 "addme", "addmeo", "addo", "addze", "addzeo",
740 "addex",
741 "addg6s",
742 "and", "andc", "andi.", "andis.",
743 "attn",
744 "absdu", "absds", # AV bitmanip
745 "absdacs", "absdacu", # AV bitmanip
746 "avgadd", # AV bitmanip
747 "b", "bc", "bcctr", "bclr", "bctar",
748 "bmask", # AV bitmanip
749 "bpermd",
750 "cbcdtd",
751 "cdtbcd",
752 "cmp", "cmpb", "cmpeqb", "cmpi", "cmpl", "cmpli", "cmprb",
753 "cntlzd", "cntlzw", "cnttzd", "cnttzw",
754 "cprop", # AV bitmanip
755 "crand", "crandc", "creqv",
756 "crnand", "crnor", "cror", "crorc", "crxor",
757 "darn",
758 "dcbf", "dcbst", "dcbt", "dcbtst", "dcbz",
759 "divd", "divde", "divdeo", "divdeu",
760 "divdeuo", "divdo", "divdu", "divduo",
761 "divmod2du",
762 "divw", "divwe", "divweo",
763 "divweu", "divweuo", "divwo", "divwu", "divwuo",
764 "dsld", "dsld.", "dsrd", "dsrd.",
765 "eieio", "eqv",
766 "extsb", "extsh", "extsw", "extswsli",
767 "fadd", "fadds", "fsub", "fsubs", # FP add / sub
768 "fcfids", "fcfidus", "fsqrts", "fres", "frsqrtes", # FP stuff
769 "fdmadds", # DCT FP 3-arg
770 "fmsubs", "fmadds", "fnmsubs", "fnmadds", # FP 3-arg
771 "ffadds", "ffsubs", "ffmuls", "ffdivs", # FFT FP 2-arg
772 "ffmsubs", "ffmadds", "ffnmsubs", "ffnmadds", # FFT FP 3-arg
773 "fmul", "fmuls", "fdiv", "fdivs", # FP mul / div
774 "fmr", "fabs", "fnabs", "fneg", "fcpsgn", # FP move/abs/neg
775 "fmvis", # FP load immediate
776 "fishmv", # Float Replace Lower-Half Single, Immediate
777 "fcvttg", "fcvttgo", "fcvttgs", "fcvttgso",
778 "fmvtg", "fmvtgs",
779 "fcvtfg", "fcvtfgs",
780 "fmvfg", "fmvfgs",
781 'grev', 'grev.', 'grevi', 'grevi.',
782 'grevw', 'grevw.', 'grevwi', 'grevwi.',
783 "hrfid", "icbi", "icbt", "isel", "isync",
784 "lbarx", "lbz", "lbzcix", "lbzu", "lbzux", "lbzx", # load byte
785 "ld", "ldarx", "ldbrx", "ldu", "ldux", "ldx", # load double
786 # "lbzbr", "lbzubr", # load byte SVP64 bit-reversed
787 # "ldbr", "ldubr", # load double SVP64 bit-reversed
788 "lfs", "lfsx", "lfsu", "lfsux", # FP load single
789 "lfd", "lfdx", "lfdu", "lfdux", "lfiwzx", "lfiwax", # FP load double
790 "lha", "lharx", "lhau", "lhaux", "lhax", # load half
791 "lhbrx", "lhz", "lhzu", "lhzux", "lhzx", # more load half
792 # "lhabr", "lhaubr", # load half SVP64 bit-reversed
793 # "lhzbr", "lhzubr", # more load half SVP64 bit-reversed
794 "lwa", "lwarx", "lwaux", "lwax", "lwbrx", # load word
795 "lwz", "lwzcix", "lwzu", "lwzux", "lwzx", # more load word
796 # "lwabr", # load word SVP64 bit-reversed
797 # "lwzbr", "lwzubr", # more load word SVP64 bit-reversed
798 "maddedu", "maddedus",
799 "maddhd", "maddhdu", "maddld", # INT multiply-and-add
800 "maddsubrs", # Integer DCT Butterfly Add Sub and Round Shift
801 "maddrs", # Integer DCT Butterfly Add and Accumulate and Round Shift
802 "mcrf", "mcrxr", "mcrxrx", "mfcr/mfocrf", # CR mvs
803 "mfmsr", "mfspr",
804 "minmax", # AV bitmanip
805 "modsd", "modsw", "modud", "moduw",
806 "mtcrf/mtocrf", "mtmsr", "mtmsrd", "mtspr",
807 "mulhd", "mulhdu", "mulhw", "mulhwu", "mulld", "mulldo",
808 "mulli", "mullw", "mullwo",
809 "nand", "neg", "nego",
810 "nop",
811 "nor", "or", "orc", "ori", "oris",
812 "pcdec",
813 "popcntb", "popcntd", "popcntw",
814 "prtyd", "prtyw",
815 "rfid",
816 "rldcl", "rldcr", "rldic", "rldicl", "rldicr", "rldimi",
817 "rlwimi", "rlwinm", "rlwnm",
818 "setb",
819 "setvl", # https://libre-soc.org/openpower/sv/setvl
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 "ternlogi",
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 OP_GREV = 88
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
966
967 class SelType(Enum):
968 NONE = None
969 SRC = 's'
970 DST = 'd'
971
972 def __repr__(self):
973 return {
974 SelType.NONE: "NONE",
975 SelType.SRC: "src",
976 SelType.DST: "dst",
977 }[self]
978
979
980 class In1Sel(Enum):
981 NONE = 0
982 RA = 1
983 RA_OR_ZERO = 2
984 SPR = 3
985 RS = 4 # for some ALU/Logical operations
986 RSp = RS
987 FRA = 5
988 FRAp = FRA
989 FRS = 6
990 FRSp = FRS
991 FRT = 7
992 CIA = 8 # for addpcis
993 RT = 9
994
995 @property
996 def type(self):
997 if self is In1Sel.NONE:
998 return SelType.NONE
999 return SelType.SRC
1000
1001
1002 class In2Sel(Enum):
1003 NONE = 0
1004 RB = 1
1005 CONST_UI = 2
1006 CONST_SI = 3
1007 CONST_UI_HI = 4
1008 CONST_SI_HI = 5
1009 CONST_LI = 6
1010 CONST_BD = 7
1011 CONST_DS = 8
1012 CONST_M1 = 9
1013 CONST_SH = 10
1014 CONST_SH32 = 11
1015 SPR = 12
1016 RS = 13 # for shiftrot (M-Form)
1017 RSp = RS
1018 FRB = 14
1019 FRBp = FRB
1020 CONST_SVD = 15 # for SVD-Form
1021 CONST_SVDS = 16 # for SVDS-Form
1022 CONST_XBI = 17
1023 CONST_DXHI4 = 18 # for addpcis
1024 CONST_DQ = 19 # for ld/st-quad
1025
1026 @property
1027 def type(self):
1028 if self is In2Sel.NONE:
1029 return SelType.NONE
1030 return SelType.SRC
1031
1032
1033 class In3Sel(Enum):
1034 NONE = 0
1035 RS = 1
1036 RSp = RS
1037 RB = 2 # for shiftrot (M-Form)
1038 FRS = 3
1039 FRSp = FRS
1040 FRC = 4
1041 RC = 5 # for SVP64 bit-reverse LD/ST
1042 RT = 6 # for ternlog[i]
1043 RTp = RT
1044 FRA = 7
1045
1046 @property
1047 def type(self):
1048 if self is In3Sel.NONE:
1049 return SelType.NONE
1050 return SelType.SRC
1051
1052
1053 class OutSel(Enum):
1054 NONE = 0
1055 RT = 1
1056 RTp = RT
1057 RA = 2
1058 SPR = 3
1059 RT_OR_ZERO = 4
1060 FRT = 5
1061 FRTp = FRT
1062 FRS = 6
1063 FRSp = FRS
1064 RS = 7
1065 RSp = RS
1066 FRA = 8
1067
1068 @property
1069 def type(self):
1070 if self is OutSel.NONE:
1071 return SelType.NONE
1072 return SelType.DST
1073
1074
1075 @unique
1076 class LDSTLen(Enum):
1077 NONE = 0
1078 is1B = 1
1079 is2B = 2
1080 is4B = 4
1081 is8B = 8
1082
1083 # Backward compatibility
1084 LdstLen = LDSTLen
1085
1086
1087 @unique
1088 class LDSTMode(Enum):
1089 NONE = 0
1090 update = 1
1091 cix = 2
1092 cx = 3
1093
1094
1095 @unique
1096 class RCOE(Enum):
1097 NONE = 0
1098 ONE = 1
1099 RC = 2 # includes OE
1100 RC_ONLY = 3 # does not include OE
1101
1102
1103 @unique
1104 class CryIn(Enum):
1105 ZERO = 0
1106 ONE = 1
1107 CA = 2
1108 OV = 3
1109
1110
1111 @unique
1112 class CRInSel(Enum):
1113 NONE = 0
1114 CR0 = 1
1115 BI = 2
1116 BFA = 3
1117 BA_BB = 4
1118 BC = 5
1119 WHOLE_REG = 6
1120 CR1 = 7
1121 BA = 8
1122
1123 @property
1124 def type(self):
1125 if self is CRInSel.NONE:
1126 return SelType.NONE
1127 return SelType.SRC
1128
1129
1130 @unique
1131 class CRIn2Sel(Enum):
1132 NONE = 0
1133 BB = 1
1134
1135 @property
1136 def type(self):
1137 if self is CRIn2Sel.NONE:
1138 return SelType.NONE
1139 return SelType.SRC
1140
1141
1142 @unique
1143 class CROutSel(Enum):
1144 NONE = 0
1145 CR0 = 1
1146 BF = 2
1147 BT = 3
1148 WHOLE_REG = 4
1149 CR1 = 5
1150
1151 @property
1152 def type(self):
1153 if self is CROutSel.NONE:
1154 return SelType.NONE
1155 return SelType.DST
1156
1157
1158 # SPRs - Special-Purpose Registers. See V3.0B Figure 18 p971 and
1159 # http://libre-riscv.org/openpower/isatables/sprs.csv
1160 # http://bugs.libre-riscv.org/show_bug.cgi?id=261
1161 # http://bugs.libre-riscv.org/show_bug.cgi?id=859 - KAIVB
1162
1163 def get_spr_enum(full_file):
1164 """get_spr_enum - creates an Enum of SPRs, dynamically
1165 has the option to reduce the enum to a much shorter list.
1166 this saves drastically on the size of the regfile
1167 """
1168 short_list = {'PIDR', 'DAR', 'PRTBL', 'DSISR', 'SVSRR0', 'SVSTATE',
1169 'SVSTATE0', 'SVSTATE1', 'SVSTATE2', 'SVSTATE3',
1170 'SPRG0_priv', 'SPRG1_priv', 'SPRG2_priv', 'SPRG3_priv',
1171 'SPRG0', 'SPRG1', 'SPRG2', 'SPRG3', 'KAIVB',
1172 # hmmm should not be including these, they are FAST regs
1173 'CTR', 'LR', 'TAR', 'SRR0', 'SRR1', 'XER', 'DEC', 'TB', 'TBU',
1174 'HSRR0', 'HSRR1', 'HSPRG0', 'HSPRG1',
1175 }
1176 spr_csv = []
1177 for row in get_csv("sprs.csv"):
1178 if full_file or row['SPR'] in short_list:
1179 spr_csv.append(row)
1180
1181 spr_info = namedtuple('spr_info', 'SPR priv_mtspr priv_mfspr length idx')
1182 spr_dict = {}
1183 spr_byname = {}
1184 for row in spr_csv:
1185 info = spr_info(SPR=row['SPR'], priv_mtspr=row['priv_mtspr'],
1186 priv_mfspr=row['priv_mfspr'], length=int(row['len']),
1187 idx=int(row['Idx']))
1188 spr_dict[int(row['Idx'])] = info
1189 spr_byname[row['SPR']] = info
1190 fields = [(row['SPR'], int(row['Idx'])) for row in spr_csv]
1191 SPR = Enum('SPR', fields)
1192 return SPR, spr_dict, spr_byname
1193
1194
1195 SPRfull, spr_dict, spr_byname = get_spr_enum(full_file=True)
1196 SPRreduced, _, _ = get_spr_enum(full_file=False)
1197
1198 XER_bits = {
1199 'SO': 32,
1200 'OV': 33,
1201 'CA': 34,
1202 'OV32': 44,
1203 'CA32': 45
1204 }
1205
1206 MSRSpec = namedtuple("MSRSpec", ["dr", "pr", "sf"])
1207
1208 # flags for bfp_* functions
1209 BFP_FLAG_NAMES = (
1210 'vxsnan_flag',
1211 'vximz_flag',
1212 'vxidi_flag',
1213 'vxisi_flag',
1214 'vxzdz_flag',
1215 'vxsqrt_flag',
1216 'vxcvi_flag',
1217 'vxvc_flag',
1218 'ox_flag',
1219 'ux_flag',
1220 'xx_flag',
1221 'zx_flag',
1222 'inc_flag',
1223 )
1224
1225 if __name__ == '__main__':
1226 # find out what the heck is in SPR enum :)
1227 print("sprs full", len(SPRfull))
1228 print(dir(SPRfull))
1229 print("sprs reduced", len(SPRreduced))
1230 print(dir(SPRreduced))
1231 print(dir(Enum))
1232 print(SPRfull.__members__['TAR'])
1233 for x in SPRfull:
1234 print("full", x, x.value, str(x), x.name)
1235 for x in SPRreduced:
1236 print("reduced", x, x.value, str(x), x.name)
1237
1238 print("function", Function.ALU.name)