power_enums: support paired registers
authorDmitry Selyutin <ghostmansd@gmail.com>
Sun, 15 Jan 2023 08:32:38 +0000 (11:32 +0300)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 2 Jun 2023 18:51:16 +0000 (19:51 +0100)
src/openpower/decoder/power_enums.py
src/openpower/decoder/power_insn.py

index 130d0815dff84f466d9be78e0fc2f0909b9f0867..e18bceb03c76fe5856327dc9604b3121a41508bb 100644 (file)
@@ -273,6 +273,12 @@ class SVExtraReg(Enum):
     BFT = auto()
     WHOLE_REG = auto()
     SPR = auto()
+    RSp = auto()
+    RTp = auto()
+    FRAp = auto()
+    FRBp = auto()
+    FRSp = auto()
+    FRTp = auto()
 
     @classmethod
     def _missing_(cls, desc):
@@ -283,7 +289,7 @@ class SVExtraReg(Enum):
         if isinstance(desc, selectors):
             return cls.__members__.get(desc.name)
 
-        return super()._missing_(desc)
+        return cls.__members__.get(desc)
 
 
 @unique
@@ -573,14 +579,20 @@ class RegType(Enum):
     RB = GPR
     RC = GPR
     RS = GPR
+    RSp = RS
     RT = GPR
+    RTp = RT
 
     FPR = 1
     FRA = FPR
+    FRAp = FRA
     FRB = FPR
+    FRBp = FRB
     FRC = FPR
     FRS = FPR
+    FRSp = FRS
     FRT = FPR
+    FRTp = FRT
 
     CR_3BIT = 2 # CR field; the CR register is 32-bit
     BF = CR_3BIT
@@ -894,19 +906,20 @@ class MicrOp(Enum):
     OP_SHADD = 103
 
 
-@unique
 class In1Sel(Enum):
     NONE = 0
     RA = 1
     RA_OR_ZERO = 2
     SPR = 3
     RS = 4  # for some ALU/Logical operations
+    RSp = RS
     FRA = 5
+    FRAp = FRA
     FRS = 6
+    FRSp = FRS
     CIA = 7 # for addpcis
 
 
-@unique
 class In2Sel(Enum):
     NONE = 0
     RB = 1
@@ -922,7 +935,9 @@ class In2Sel(Enum):
     CONST_SH32 = 11
     SPR = 12
     RS = 13  # for shiftrot (M-Form)
+    RSp = RS
     FRB = 14
+    FRBp = FRB
     CONST_SVD = 15  # for SVD-Form
     CONST_SVDS = 16  # for SVDS-Form
     CONST_XBI = 17
@@ -930,27 +945,32 @@ class In2Sel(Enum):
     CONST_DQ = 19 # for ld/st-quad
 
 
-@unique
 class In3Sel(Enum):
     NONE = 0
     RS = 1
+    RSp = RS
     RB = 2  # for shiftrot (M-Form)
     FRS = 3
+    FRSp = FRS
     FRC = 4
     RC = 5  # for SVP64 bit-reverse LD/ST
     RT = 6  # for ternlog[i]
+    RTp = RT
 
 
-@unique
 class OutSel(Enum):
     NONE = 0
     RT = 1
+    RTp = RT
     RA = 2
     SPR = 3
     RT_OR_ZERO = 4
     FRT = 5
+    FRTp = FRT
     FRS = 6
+    FRSp = FRS
     RS = 7
+    RSp = RS
 
 
 @unique
index e55b03fb95e7d0e888dccd00156b9ae4b862f21f..e90b987e9aaa1c2affc6bc7ae5f7d4e605494d6d 100644 (file)
@@ -575,6 +575,17 @@ class Fields:
 
 
 class Operands:
+    __GPR_PAIRS = (
+        _SVExtraReg.RTp,
+        _SVExtraReg.RSp,
+    )
+    __FPR_PAIRS = (
+        _SVExtraReg.FRAp,
+        _SVExtraReg.FRBp,
+        _SVExtraReg.FRSp,
+        _SVExtraReg.FRTp,
+    )
+
     def __init__(self, insn, iterable):
         custom_insns = {
             "b": {"target_addr": TargetAddrOperandLI},
@@ -603,6 +614,12 @@ class Operands:
             "SIM": SignedOperand,
             "SVD": SignedOperand,
             "SVDS": SignedOperand,
+            "RSp": GPRPairOperand,
+            "RTp": GPRPairOperand,
+            "FRAp": FPRPairOperand,
+            "FRBp": FPRPairOperand,
+            "FRSp": FPRPairOperand,
+            "FRTp": FPRPairOperand,
         }
         custom_immediates = {
             "DQ": EXTSOperandDQ,
@@ -635,16 +652,22 @@ class Operands:
                 elif name in custom_fields:
                     cls = custom_fields[name]
 
-                if name in _RegType.__members__:
-                    regtype = _RegType[name]
-                    if regtype is _RegType.GPR:
-                        cls = GPROperand
-                    elif regtype is _RegType.FPR:
-                        cls = FPROperand
-                    if regtype is _RegType.CR_5BIT:
-                        cls = CR5Operand
-                    if regtype is _RegType.CR_3BIT:
-                        cls = CR3Operand
+                if name in _SVExtraReg.__members__:
+                    reg = _SVExtraReg[name]
+                    if reg in self.__class__.__GPR_PAIRS:
+                        cls = GPRPairOperand
+                    elif reg in self.__class__.__FPR_PAIRS:
+                        cls = FPRPairOperand
+                    else:
+                        regtype = _RegType[name]
+                        if regtype is _RegType.GPR:
+                            cls = GPROperand
+                        elif regtype is _RegType.FPR:
+                            cls = FPROperand
+                        elif regtype is _RegType.CR_5BIT:
+                            cls = CR5Operand
+                        elif regtype is _RegType.CR_3BIT:
+                            cls = CR3Operand
 
                 if imm_name is not None:
                     mapping[imm_name] = (imm_cls, {"name": imm_name})
@@ -1172,12 +1195,21 @@ class ExtendableOperand(DynamicOperand):
 
     @property
     def extra_idx(self):
+        pairs = {
+            _SVExtraReg.RSp: _SVExtraReg.RS,
+            _SVExtraReg.RTp: _SVExtraReg.RT,
+            _SVExtraReg.FRAp: _SVExtraReg.FRA,
+            _SVExtraReg.FRBp: _SVExtraReg.FRB,
+            _SVExtraReg.FRSp: _SVExtraReg.FRS,
+            _SVExtraReg.FRTp: _SVExtraReg.FRT,
+        }
+
         for key in frozenset({
                     "in1", "in2", "in3", "cr_in", "cr_in2",
                     "out", "out2", "cr_out",
                 }):
             extra_reg = self.record.svp64.extra_reg(key=key)
-            if extra_reg is self.extra_reg:
+            if pairs.get(extra_reg, extra_reg) is pairs.get(self.extra_reg, self.extra_reg):
                 return self.record.extra_idx(key=key)
 
         return _SVExtra.NONE
@@ -1285,6 +1317,11 @@ class GPROperand(SimpleRegisterOperand):
             verbosity=verbosity, indent=indent)
 
 
+@_dataclasses.dataclass(eq=True, frozen=True)
+class GPRPairOperand(GPROperand):
+    pass
+
+
 @_dataclasses.dataclass(eq=True, frozen=True)
 class FPROperand(SimpleRegisterOperand):
     def assemble(self, value, insn):
@@ -1297,6 +1334,11 @@ class FPROperand(SimpleRegisterOperand):
             verbosity=verbosity, indent=indent)
 
 
+@_dataclasses.dataclass(eq=True, frozen=True)
+class FPRPairOperand(FPROperand):
+    pass
+
+
 @_dataclasses.dataclass(eq=True, frozen=True)
 class ConditionRegisterFieldOperand(ExtendableOperand):
     def pattern(name_pattern):