From 6b017d4386f42405baa4f65b18ec136309715e4b Mon Sep 17 00:00:00 2001 From: Dmitry Selyutin Date: Mon, 7 Nov 2022 21:54:35 +0300 Subject: [PATCH] power_insn: support CR operands assembly --- src/openpower/decoder/power_insn.py | 110 +++++++++++++++++++++++++++- 1 file changed, 107 insertions(+), 3 deletions(-) diff --git a/src/openpower/decoder/power_insn.py b/src/openpower/decoder/power_insn.py index 117997b1..5403c944 100644 --- a/src/openpower/decoder/power_insn.py +++ b/src/openpower/decoder/power_insn.py @@ -1229,12 +1229,116 @@ class FPROperand(SimpleRegisterOperand): @_dataclasses.dataclass(eq=True, frozen=True) -class CR3Operand(ExtendableOperand): - pass +class ConditionRegisterFieldOperand(ExtendableOperand): + def pattern(name_pattern): + (name, pattern) = name_pattern + return (name, _re.compile(f"^{pattern}$", _re.S)) + + CONDS = { + "lt": 0, + "gt": 1, + "eq": 2, + "so": 3, + "un": 3, + } + CR = r"(?:CR|cr)([0-9]+)" + N = r"([0-9]+)" + BIT = rf"({'|'.join(CONDS.keys())})" + LBIT = fr"{BIT}\s*\+\s*" # BIT+ + RBIT = fr"\s*\+\s*{BIT}" # +BIT + CRN = fr"{CR}\s*\*\s*{N}" # CR*N + NCR = fr"{N}\s*\*\s*{CR}" # N*CR + XCR = fr"{CR}\.{BIT}" + PATTERNS = tuple(map(pattern, ( + ("CR", CR), + ("CR_BIT", XCR), + ("CR*N", CRN), + ("N*CR", NCR), + ("BIT+CR", (LBIT + CR)), + ("CR+BIT", (CR + RBIT)), + ("BIT+CR*N", (LBIT + CRN)), + ("CR*N+BIT", (CRN + RBIT)), + ("BIT+N*CR", (LBIT + NCR)), + ("N*CR+BIT", (NCR + RBIT)), + ))) + + def remap(self, value, vector, regtype): + if regtype is _RegType.CR_BIT: + subvalue = (value & 0x3) + value >>= 2 + + if vector: + extra = (value & 0xf) + value >>= 4 + else: + extra = (value >> 3) + value &= 0x7 + + if self.record.etype is _SVEtype.EXTRA2: + if vector: + assert (extra & 0x7) == 0, \ + "vector CR cannot fit into EXTRA2" + extra = (0x2 | (extra >> 3)) + else: + assert (extra >> 1) == 0, \ + "scalar CR cannot fit into EXTRA2" + extra &= 0x1 + elif self.record.etype is _SVEtype.EXTRA3: + if vector: + assert (extra & 0x3) == 0, \ + "vector CR cannot fit into EXTRA3" + extra = (0x4 | (extra >> 2)) + else: + assert (extra >> 2) == 0, \ + "scalar CR cannot fit into EXTRA3" + extra &= 0x3 + + if regtype is _RegType.CR_BIT: + value = ((value << 2) | subvalue) + + return (value, extra) + + def assemble(self, value, insn): + if isinstance(value, str): + vector = False + + if value.startswith("*"): + if not isinstance(insn, SVP64Instruction): + raise ValueError(value) + value = value[1:] + vector = True + + for (name, pattern) in reversed(self.__class__.PATTERNS): + match = pattern.match(value) + if match is not None: + keys = name.replace("+", "_").replace("*", "_").split("_") + values = match.groups() + match = dict(zip(keys, values)) + CR = int(match["CR"]) + if name == "CR_BIT": + N = 4 + else: + N = int(match.get("N", "1")) + BIT = self.__class__.CONDS[match.get("BIT", "lt")] + value = ((CR * N) + BIT) + break + + return super().assemble(value=value, insn=insn, prefix="cr") + + +@_dataclasses.dataclass(eq=True, frozen=True) +class CR3Operand(ConditionRegisterFieldOperand): + def remap(self, value, vector): + return super().remap(value=value, vector=vector, + regtype=_RegType.CR_REG) @_dataclasses.dataclass(eq=True, frozen=True) -class CR5Operand(ExtendableOperand): +class CR5Operand(ConditionRegisterFieldOperand): + def remap(self, value, vector): + return super().remap(value=value, vector=vector, + regtype=_RegType.CR_BIT) + def sv_spec_enter(self, value, span): value = _SelectableInt(value=(value.value >> 2), bits=3) return (value, span) -- 2.30.2