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