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