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