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