From 41ec342e61d71896fb3eef6798b221f0dfa98cbf Mon Sep 17 00:00:00 2001 From: Dmitry Selyutin Date: Sun, 15 Jan 2023 11:32:38 +0300 Subject: [PATCH] power_enums: support paired registers --- src/openpower/decoder/power_enums.py | 30 ++++++++++--- src/openpower/decoder/power_insn.py | 64 +++++++++++++++++++++++----- 2 files changed, 78 insertions(+), 16 deletions(-) diff --git a/src/openpower/decoder/power_enums.py b/src/openpower/decoder/power_enums.py index 130d0815..e18bceb0 100644 --- a/src/openpower/decoder/power_enums.py +++ b/src/openpower/decoder/power_enums.py @@ -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 diff --git a/src/openpower/decoder/power_insn.py b/src/openpower/decoder/power_insn.py index e55b03fb..e90b987e 100644 --- a/src/openpower/decoder/power_insn.py +++ b/src/openpower/decoder/power_insn.py @@ -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): -- 2.30.2