From: Dmitry Selyutin Date: Sat, 3 Sep 2022 20:15:54 +0000 (+0300) Subject: power_insn: support PPC multi-records X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=1c7a922abdd5f14b535a5fea7de8f2386784bd51;p=openpower-isa.git power_insn: support PPC multi-records --- diff --git a/src/openpower/decoder/power_insn.py b/src/openpower/decoder/power_insn.py index a655111e..d4baa447 100644 --- a/src/openpower/decoder/power_insn.py +++ b/src/openpower/decoder/power_insn.py @@ -234,6 +234,38 @@ class PPCRecord: return frozenset(self.comment.split("=")[-1].split("/")) +class PPCMultiRecord(tuple): + @cached_property + def unified(self): + def merge(lhs, rhs): + value = 0 + mask = 0 + lvalue = lhs.opcode.value + rvalue = rhs.opcode.value + lmask = lhs.opcode.mask + rmask = rhs.opcode.mask + bits = max(lmask.bit_length(), rmask.bit_length()) + for bit in range(bits): + lvstate = ((lvalue & (1 << bit)) != 0) + rvstate = ((rvalue & (1 << bit)) != 0) + lmstate = ((lmask & (1 << bit)) != 0) + rmstate = ((rmask & (1 << bit)) != 0) + vstate = lvstate + mstate = True + if (not lmstate or not rmstate) or (lvstate != rvstate): + vstate = 0 + mstate = 0 + value |= (vstate << bit) + mask |= (mstate << bit) + + return _dataclasses.replace(lhs, opcode=Opcode(value=value, mask=mask)) + + return _functools.reduce(merge, self) + + def __getattr__(self, attr): + return getattr(self.unified, attr) + + @_dataclasses.dataclass(eq=True, frozen=True) class SVP64Record: class ExtraMap(tuple): @@ -1186,38 +1218,10 @@ class PPCDatabase: for insn in parse(stream, factory): records[section][insn.comment].add(insn) - # Once we collected all instructions with the same identifier, - # it's time to merge the different opcodes into the single pattern. - # At this point, we only consider masks; the algorithm as follows: - # 1. If any of two masks ignores the bit, it's ignored entirely. - # 2. If the bit is not equal between masks, it's ignored. - # 3. Otherwise the bits are equal and considered. - def merge(lhs, rhs): - value = 0 - mask = 0 - lvalue = lhs.opcode.value - rvalue = rhs.opcode.value - lmask = lhs.opcode.mask - rmask = rhs.opcode.mask - bits = max(lmask.bit_length(), rmask.bit_length()) - for bit in range(bits): - lvstate = ((lvalue & (1 << bit)) != 0) - rvstate = ((rvalue & (1 << bit)) != 0) - lmstate = ((lmask & (1 << bit)) != 0) - rmstate = ((rmask & (1 << bit)) != 0) - vstate = lvstate - mstate = True - if (not lmstate or not rmstate) or (lvstate != rvstate): - vstate = 0 - mstate = 0 - value |= (vstate << bit) - mask |= (mstate << bit) - return _dataclasses.replace(lhs, opcode=Opcode(value=value, mask=mask)) - db = dd(set) for (section, group) in records.items(): for records in group.values(): - db[section].add(_functools.reduce(merge, records)) + db[section].add(PPCMultiRecord(records)) self.__db = db self.__mdwndb = mdwndb