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 "crbinlog", "crfbinlog", # binary bitmanip (field and CR bit)
753 "crternlogi", "crfternlogi", # ternary bitmanip (field and CR bit)
754 "darn",
755 "dcbf", "dcbst", "dcbt", "dcbtst", "dcbz",
756 "divd", "divde", "divdeo", "divdeu",
757 "divdeuo", "divdo", "divdu", "divduo",
758 "divmod2du",
759 "divw", "divwe", "divweo",
760 "divweu", "divweuo", "divwo", "divwu", "divwuo",
761 "dsld", "dsld.", "dsrd", "dsrd.",
762 "eieio", "eqv",
763 "extsb", "extsh", "extsw", "extswsli",
764 "fadd", "fadds", "fsub", "fsubs", # FP add / sub
765 "fcfids", "fcfidus", "fsqrts", "fres", "frsqrtes", # FP stuff
766 "fdmadds", # DCT FP 3-arg
767 "fmsubs", "fmadds", "fnmsubs", "fnmadds", # FP 3-arg
768 "ffadds", "ffsubs", "ffmuls", "ffdivs", # FFT FP 2-arg
769 "ffmsubs", "ffmadds", "ffnmsubs", "ffnmadds", # FFT FP 3-arg
770 "fmul", "fmuls", "fdiv", "fdivs", # FP mul / div
771 "fmr", "fabs", "fnabs", "fneg", "fcpsgn", # FP move/abs/neg
772 "fmvis", # FP load immediate
773 "fishmv", # Float Replace Lower-Half Single, Immediate
774 "gbbd", # bitmanip - (aka bmatflip)
775 "cffpr", "cffpro",
776 "mffpr", "mffprs",
777 "ctfpr", "ctfprs",
778 "mtfpr", "mtfprs",
779 "hrfid", "icbi", "icbt", "isel", "isync",
780 "lbarx", "lbz", "lbzcix", "lbzu", "lbzux", "lbzx", # load byte
781 "ld", "ldarx", "ldbrx", "ldu", "ldux", "ldx", # load double
782 # "lbzbr", "lbzubr", # load byte SVP64 bit-reversed
783 # "ldbr", "ldubr", # load double SVP64 bit-reversed
784 "lfs", "lfsx", "lfsu", "lfsux", # FP load single
785 "lfd", "lfdx", "lfdu", "lfdux", "lfiwzx", "lfiwax", # FP load double
786 "lha", "lharx", "lhau", "lhaux", "lhax", # load half
787 "lhbrx", "lhz", "lhzu", "lhzux", "lhzx", # more load half
788 # "lhabr", "lhaubr", # load half SVP64 bit-reversed
789 # "lhzbr", "lhzubr", # more load half SVP64 bit-reversed
790 "lwa", "lwarx", "lwaux", "lwax", "lwbrx", # load word
791 "lwz", "lwzcix", "lwzu", "lwzux", "lwzx", # more load word
792 # "lwabr", # load word SVP64 bit-reversed
793 # "lwzbr", "lwzubr", # more load word SVP64 bit-reversed
794 "maddedu", "maddedus",
795 "maddhd", "maddhdu", "maddld", # INT multiply-and-add
796 "maddsubrs", # Int DCT Butterfly Add Sub and Round Shift
797 "maddrs", # Int DCT Butterfly Add and Accumulate and Round Shift
798 "msubrs", # Int DCT Butterfly Subtract from and Round Shift
799 "mcrf", "mcrxr", "mcrxrx", "mfcr/mfocrf", # CR mvs
800 "mfmsr", "mfspr",
801 "minmax", # AV bitmanip
802 "modsd", "modsw", "modud", "moduw",
803 "mtcrf/mtocrf", "mtmsr", "mtmsrd", "mtspr",
804 "mulhd", "mulhdu", "mulhw", "mulhwu", "mulld", "mulldo",
805 "mulli", "mullw", "mullwo",
806 "nand", "neg", "nego",
807 "nop",
808 "nor", "or", "orc", "ori", "oris",
809 "pcdec",
810 "pdepd", "pextd",
811 "popcntb", "popcntd", "popcntw",
812 "prtyd", "prtyw",
813 "rfid",
814 "rldcl", "rldcr", "rldic", "rldicl", "rldicr", "rldimi",
815 "rlwimi", "rlwinm", "rlwnm",
816 "setb",
817 "setbc", "setbcr", "setnbc", "setnbcr",
818 "setvl", # https://libre-soc.org/openpower/sv/setvl
819 "sc", "scv",
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 "binlog", "ternlogi", # binary/ternary (lut2/lut3)
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 # 88 available
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 OP_MSUBRS = 106
966 OP_BYTEREV = 107
967 OP_CFUGE = 108
968 OP_PDEP = 109
969 OP_PEXT = 110
970 OP_SETBC = 111
971 OP_BMAT = 112 # bmatflip/xor/and - known by many names (vgbbd in Power)
972 OP_CRTERNLOG = 113
973 <<<<<<< HEAD
974 OP_BINLOG = 114
975 OP_CRBINLOG = 115
976 OP_CRFBINLOG = 116
977 OP_CRFTERNLOG = 117
978 =======
979 >>>>>>> ef668555 (bug 1034: add crternlogi. involved adding a new CR field BFA_BFB_BF sigh)
980
981
982 class SelType(Enum):
983 NONE = None
984 SRC = 's'
985 DST = 'd'
986
987 def __str__(self):
988 return {
989 SelType.NONE: "NONE",
990 SelType.SRC: "SRC",
991 SelType.DST: "DST",
992 }[self]
993
994
995 class In1Sel(Enum):
996 NONE = 0
997 RA = 1
998 RA_OR_ZERO = 2
999 SPR = 3
1000 RS = 4 # for some ALU/Logical operations
1001 RSp = RS
1002 FRA = 5
1003 FRAp = FRA
1004 FRS = 6
1005 FRSp = FRS
1006 FRT = 7
1007 CIA = 8 # for addpcis
1008 RT = 9
1009
1010 def __str__(self):
1011 if self is In1Sel.RA_OR_ZERO:
1012 return "RA0"
1013 return self.name
1014
1015 @property
1016 def type(self):
1017 if self is In1Sel.NONE:
1018 return SelType.NONE
1019 return SelType.SRC
1020
1021
1022 class In2Sel(Enum):
1023 NONE = 0
1024 RB = 1
1025 CONST_UI = 2
1026 CONST_SI = 3
1027 CONST_UI_HI = 4
1028 CONST_SI_HI = 5
1029 CONST_LI = 6
1030 CONST_BD = 7
1031 CONST_DS = 8
1032 CONST_M1 = 9
1033 CONST_SH = 10
1034 CONST_SH32 = 11
1035 SPR = 12
1036 RS = 13 # for shiftrot (M-Form)
1037 RSp = RS
1038 FRB = 14
1039 FRBp = FRB
1040 CONST_SVD = 15 # for SVD-Form
1041 CONST_SVDS = 16 # for SVDS-Form
1042 # 17 available
1043 CONST_DXHI4 = 18 # for addpcis
1044 CONST_DQ = 19 # for ld/st-quad
1045
1046 def __str__(self):
1047 return self.name
1048
1049 @property
1050 def type(self):
1051 if self is In2Sel.NONE:
1052 return SelType.NONE
1053 return SelType.SRC
1054
1055
1056 class In3Sel(Enum):
1057 NONE = 0
1058 RS = 1
1059 RSp = RS
1060 RB = 2 # for shiftrot (M-Form)
1061 FRS = 3
1062 FRSp = FRS
1063 FRC = 4
1064 RC = 5 # for SVP64 bit-reverse LD/ST
1065 RT = 6 # for ternlog[i]
1066 RTp = RT
1067 FRA = 7
1068
1069 def __str__(self):
1070 return self.name
1071
1072 @property
1073 def type(self):
1074 if self is In3Sel.NONE:
1075 return SelType.NONE
1076 return SelType.SRC
1077
1078
1079 class OutSel(Enum):
1080 NONE = 0
1081 RT = 1
1082 RTp = RT
1083 RA = 2
1084 SPR = 3
1085 RT_OR_ZERO = 4
1086 FRT = 5
1087 FRTp = FRT
1088 FRS = 6
1089 FRSp = FRS
1090 RS = 7
1091 RSp = RS
1092 FRA = 8
1093
1094 def __str__(self):
1095 if self is OutSel.RT_OR_ZERO:
1096 return "RT0"
1097 return self.name
1098
1099 @property
1100 def type(self):
1101 if self is OutSel.NONE:
1102 return SelType.NONE
1103 return SelType.DST
1104
1105
1106 @unique
1107 class LDSTLen(Enum):
1108 NONE = 0
1109 is1B = 1
1110 is2B = 2
1111 is4B = 4
1112 is8B = 8
1113
1114 # Backward compatibility
1115 LdstLen = LDSTLen
1116
1117
1118 @unique
1119 class LDSTMode(Enum):
1120 NONE = 0
1121 update = 1
1122 cix = 2
1123 cx = 3
1124
1125
1126 @unique
1127 class RCOE(Enum):
1128 NONE = 0
1129 ONE = 1
1130 RC = 2 # includes OE
1131 RC_ONLY = 3 # does not include OE
1132
1133
1134 @unique
1135 class CryIn(Enum):
1136 ZERO = 0
1137 ONE = 1
1138 CA = 2
1139 OV = 3
1140
1141
1142 @unique
1143 class CRInSel(Enum):
1144 NONE = 0
1145 CR0 = 1
1146 BI = 2
1147 BFA = 3
1148 BA_BB = 4
1149 BC = 5
1150 WHOLE_REG = 6
1151 CR1 = 7
1152 BA = 8
1153 BFA_BFB_BF = 9
1154 BA_BFB = 10 # maaamma miiia... definitely time for CRin1/2 in CSV...
1155
1156 def __str__(self):
1157 return self.name
1158
1159 @property
1160 def type(self):
1161 if self is CRInSel.NONE:
1162 return SelType.NONE
1163 return SelType.SRC
1164
1165
1166 @unique
1167 class CRIn2Sel(Enum):
1168 NONE = 0
1169 BB = 1
1170 BFB = 2
1171
1172 def __str__(self):
1173 return self.name
1174
1175 @property
1176 def type(self):
1177 if self is CRIn2Sel.NONE:
1178 return SelType.NONE
1179 return SelType.SRC
1180
1181
1182 @unique
1183 class CROutSel(Enum):
1184 NONE = 0
1185 CR0 = 1
1186 BF = 2
1187 BT = 3
1188 WHOLE_REG = 4
1189 CR1 = 5
1190
1191 def __str__(self):
1192 return self.name
1193
1194 @property
1195 def type(self):
1196 if self is CROutSel.NONE:
1197 return SelType.NONE
1198 return SelType.DST
1199
1200
1201 # SPRs - Special-Purpose Registers. See V3.0B Figure 18 p971 and
1202 # http://libre-riscv.org/openpower/isatables/sprs.csv
1203 # http://bugs.libre-riscv.org/show_bug.cgi?id=261
1204 # http://bugs.libre-riscv.org/show_bug.cgi?id=859 - KAIVB
1205
1206 def get_spr_enum(full_file):
1207 """get_spr_enum - creates an Enum of SPRs, dynamically
1208 has the option to reduce the enum to a much shorter list.
1209 this saves drastically on the size of the regfile
1210 """
1211 short_list = {'PIDR', 'DAR', 'PRTBL', 'DSISR', 'SVSRR0', 'SVSTATE',
1212 'SVSTATE0', 'SVSTATE1', 'SVSTATE2', 'SVSTATE3',
1213 'SPRG0_priv', 'SPRG1_priv', 'SPRG2_priv', 'SPRG3_priv',
1214 'SPRG0', 'SPRG1', 'SPRG2', 'SPRG3', 'KAIVB',
1215 # hmmm should not be including these, they are FAST regs
1216 'CTR', 'LR', 'TAR', 'SRR0', 'SRR1', 'XER', 'DEC', 'TB', 'TBU',
1217 'HSRR0', 'HSRR1', 'HSPRG0', 'HSPRG1',
1218 }
1219 spr_csv = []
1220 for row in get_csv("sprs.csv"):
1221 if full_file or row['SPR'] in short_list:
1222 spr_csv.append(row)
1223
1224 spr_info = namedtuple('spr_info', 'SPR priv_mtspr priv_mfspr length idx')
1225 spr_dict = {}
1226 spr_byname = {}
1227 for row in spr_csv:
1228 info = spr_info(SPR=row['SPR'], priv_mtspr=row['priv_mtspr'],
1229 priv_mfspr=row['priv_mfspr'], length=int(row['len']),
1230 idx=int(row['Idx']))
1231 spr_dict[int(row['Idx'])] = info
1232 spr_byname[row['SPR']] = info
1233 fields = [(row['SPR'], int(row['Idx'])) for row in spr_csv]
1234 SPR = Enum('SPR', fields)
1235 return SPR, spr_dict, spr_byname
1236
1237
1238 SPRfull, spr_dict, spr_byname = get_spr_enum(full_file=True)
1239 SPRreduced, _, _ = get_spr_enum(full_file=False)
1240
1241 XER_bits = {
1242 'SO': 32,
1243 'OV': 33,
1244 'CA': 34,
1245 'OV32': 44,
1246 'CA32': 45
1247 }
1248
1249 MSRSpec = namedtuple("MSRSpec", ["dr", "pr", "sf"])
1250
1251 # flags for bfp_* functions
1252 BFP_FLAG_NAMES = (
1253 'vxsnan_flag',
1254 'vximz_flag',
1255 'vxidi_flag',
1256 'vxisi_flag',
1257 'vxzdz_flag',
1258 'vxsqrt_flag',
1259 'vxcvi_flag',
1260 'vxvc_flag',
1261 'ox_flag',
1262 'ux_flag',
1263 'xx_flag',
1264 'zx_flag',
1265 'inc_flag',
1266 )
1267
1268
1269 @unique
1270 class FMinMaxMode(Enum):
1271 """ FMM field for fminmax instruction.
1272 enumerant names match assembly aliases.
1273 """
1274 fminnum08 = 0b0000
1275 fmin19 = 0b0001
1276 fminnum19 = 0b0010
1277 fminc = 0b0011
1278 fminmagnum08 = 0b0100
1279 fminmag19 = 0b0101
1280 fminmagnum19 = 0b0110
1281 fminmagc = 0b0111
1282 fmaxnum08 = 0b1000
1283 fmax19 = 0b1001
1284 fmaxnum19 = 0b1010
1285 fmaxc = 0b1011
1286 fmaxmagnum08 = 0b1100
1287 fmaxmag19 = 0b1101
1288 fmaxmagnum19 = 0b1110
1289 fmaxmagc = 0b1111
1290
1291 if __name__ == '__main__':
1292 # find out what the heck is in SPR enum :)
1293 print("sprs full", len(SPRfull))
1294 print(dir(SPRfull))
1295 print("sprs reduced", len(SPRreduced))
1296 print(dir(SPRreduced))
1297 print(dir(Enum))
1298 print(SPRfull.__members__['TAR'])
1299 for x in SPRfull:
1300 print("full", x, x.value, str(x), x.name)
1301 for x in SPRreduced:
1302 print("reduced", x, x.value, str(x), x.name)
1303
1304 print("function", Function.ALU.name)