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