power_enums: introduce RegType enum
[openpower-isa.git] / src / openpower / decoder / power_enums.py
index d5ffffab88179f805ef65015216fe6f799a00773..78015c362dea09d04358704034a7e4205260f0c1 100644 (file)
@@ -14,11 +14,15 @@ regfile size in HDL.  this is SPRreduced and the supported list is in
 get_spr_enum
 """
 
-from enum import Enum, unique
+from enum import (
+    Enum as _Enum,
+    unique,
+)
 import csv
 import os
 from os.path import dirname, join
 from collections import namedtuple
+import functools
 
 
 def find_wiki_dir():
@@ -63,6 +67,26 @@ def get_signal_name(name):
         name = "is_" + name
     return name.lower().replace(' ', '_')
 
+
+class Enum(_Enum):
+    @classmethod
+    def _missing_(cls, value):
+        if isinstance(value, str):
+            try:
+                if value == "":
+                    value = 0
+                else:
+                    value = int(value, 0)
+            except ValueError:
+                pass
+        keys = {item.name:item for item in cls}
+        values = {item.value:item for item in cls}
+        item = keys.get(value, values.get(value))
+        if item is None:
+            raise ValueError(value)
+        return item
+
+
 # this corresponds to which Function Unit (pipeline-with-Reservation-Stations)
 # is to process and guard the operation.  they are roughly divided by having
 # the same register input/output signature (X-Form, etc.)
@@ -86,6 +110,20 @@ class Function(Enum):
     VL = 1 << 13  # setvl
     FPU = 1 << 14  # FPU
 
+    @functools.lru_cache(maxsize=None)
+    def __repr__(self):
+        counter = 0
+        value = int(self.value)
+        if value != 0:
+            while value != 0:
+                counter += 1
+                value >>= 1
+            counter -= 1
+            desc = f"(1 << {counter})"
+        else:
+            desc = "0"
+        return f"<{self.__class__.__name__}.{self.name}: {desc}>"
+
 
 @unique
 class Form(Enum):
@@ -140,6 +178,10 @@ class SVPtype(Enum):
     P1 = 1
     P2 = 2
 
+    @classmethod
+    def _missing_(cls, value):
+        return {"1P": SVPtype.P1, "2P": SVPtype.P2}[value]
+
 
 @unique
 class SVEtype(Enum):
@@ -258,6 +300,34 @@ class SVP64LDSTmode(Enum):
     UNITSTRIDE = 3
 
 
+class RegType(Enum):
+    GPR = 0
+    RA = GPR
+    RB = GPR
+    RC = GPR
+    RS = GPR
+    RT = GPR
+
+    FPR = 1
+    FRA = FPR
+    FRB = FPR
+    FRC = FPR
+    FRS = FPR
+    FRT = FPR
+
+    CR_REG = 2
+    BF = CR_REG
+    BFA = CR_REG
+
+    CR_BIT = 3
+    BA = CR_BIT
+    BB = CR_BIT
+    BC = CR_BIT
+    BI = CR_BIT
+    BT = CR_BIT
+    BFT = CR_BIT
+
+
 # supported instructions: make sure to keep up-to-date with CSV files
 # just like everything else
 _insns = [
@@ -525,13 +595,16 @@ class OutSel(Enum):
 
 
 @unique
-class LdstLen(Enum):
+class LDSTLen(Enum):
     NONE = 0
     is1B = 1
     is2B = 2
     is4B = 4
     is8B = 8
 
+# Backward compatibility
+LdstLen = LDSTLen
+
 
 @unique
 class LDSTMode(Enum):