+ raise ValueError(record.etype)
+
+ if spec != 0:
+ vector = bool(spec[0])
+ spec_span = spec.__class__
+ if record.etype is _SVEtype.EXTRA3:
+ spec_span = tuple(map(str, spec_span[1, 2]))
+ spec = spec[1, 2]
+ elif record.etype is _SVEtype.EXTRA2:
+ spec_span = tuple(map(str, spec_span[1,]))
+ spec = _SelectableInt(value=spec[1].value, bits=2)
+ if vector:
+ spec <<= 1
+ spec_span = (spec_span + ("{0}",))
+ else:
+ spec_span = (("{0}",) + spec_span)
+ else:
+ raise ValueError(record.etype)
+
+ vector_shift = (2 + (5 - value.bits))
+ scalar_shift = value.bits
+ spec_shift = (5 - value.bits)
+
+ bits = (len(span) + len(spec_span))
+ value = _SelectableInt(value=value.value, bits=bits)
+ spec = _SelectableInt(value=spec.value, bits=bits)
+ if vector:
+ value = ((value << vector_shift) | (spec << spec_shift))
+ span = (span + spec_span + ((spec_shift * ('{0}',))))
+ else:
+ value = ((spec << scalar_shift) | value)
+ span = ((spec_shift * ('{0}',)) + spec_span + span)
+
+ (value, span) = self.sv_spec_leave(value=value, span=span,
+ origin_value=origin_value, origin_span=origin_span)
+
+ return (vector, value, span)
+
+ @property
+ def extra_reg(self):
+ return _SVExtraReg(self.name)
+
+ def extra_idx(self, record):
+ for key in frozenset({
+ "in1", "in2", "in3", "cr_in", "cr_in2",
+ "out", "out2", "cr_out",
+ }):
+ extra_reg = record.svp64.extra_reg(key=key)
+ if extra_reg is self.extra_reg:
+ return record.extra_idx(key=key)
+
+ return _SVExtra.NONE
+
+ def disassemble(self, insn, record,
+ verbosity=Verbosity.NORMAL, prefix="", indent=""):
+ (vector, value, span) = self.spec(insn=insn, record=record)
+
+ if verbosity >= Verbosity.VERBOSE:
+ mode = "vector" if vector else "scalar"
+ yield f"{indent}{self.name} ({mode})"
+ yield f"{indent}{indent}{int(value):0{value.bits}b}"
+ yield f"{indent}{indent}{', '.join(span)}"
+ if isinstance(insn, SVP64Instruction):
+ extra_idx = self.extra_idx(record)
+ if record.etype is _SVEtype.NONE:
+ yield f"{indent}{indent}extra[none]"
+ else:
+ etype = repr(record.etype).lower()
+ yield f"{indent}{indent}{etype}{extra_idx!r}"
+ else:
+ vector = "*" if vector else ""
+ yield f"{vector}{prefix}{int(value)}"
+
+
+class GPROperand(RegisterOperand):
+ def disassemble(self, insn, record,
+ verbosity=Verbosity.NORMAL, indent=""):
+ prefix = "" if (verbosity <= Verbosity.SHORT) else "r"
+ yield from super().disassemble(prefix=prefix,
+ insn=insn, record=record,
+ verbosity=verbosity, indent=indent)
+
+
+class FPROperand(RegisterOperand):
+ def disassemble(self, insn, record,
+ verbosity=Verbosity.NORMAL, indent=""):
+ prefix = "" if (verbosity <= Verbosity.SHORT) else "f"
+ yield from super().disassemble(prefix=prefix,
+ insn=insn, record=record,
+ verbosity=verbosity, indent=indent)
+
+
+class CR3Operand(RegisterOperand):
+ pass
+
+
+class CR5Operand(RegisterOperand):
+ def sv_spec_enter(self, value, span):
+ value = _SelectableInt(value=(value.value >> 2), bits=3)
+ return (value, span)
+
+ def sv_spec_leave(self, value, span, origin_value, origin_span):
+ value = _selectconcat(value, origin_value[3:5])
+ span += origin_span
+ return (value, span)
+
+
+class TargetAddrOperand(RegisterOperand):
+ def disassemble(self, insn, record, field,
+ verbosity=Verbosity.NORMAL, indent=""):
+ span = self.span(record=record)
+ if isinstance(insn, SVP64Instruction):
+ span = tuple(map(lambda bit: (bit + 32), span))
+ value = insn[span]
+
+ if verbosity >= Verbosity.VERBOSE:
+ span = tuple(map(str, span))
+ yield f"{indent}{self.name} = EXTS({field} || 0b00))"
+ yield f"{indent}{indent}{field}"
+ yield f"{indent}{indent}{indent}{int(value):0{value.bits}b}00"
+ yield f"{indent}{indent}{indent}{', '.join(span + ('{0}', '{0}'))}"
+ else:
+ yield hex(_selectconcat(value,
+ _SelectableInt(value=0b00, bits=2)).to_signed_int())
+
+
+class TargetAddrOperandLI(TargetAddrOperand):
+ def span(self, record):
+ return record.fields["LI"]
+
+ def disassemble(self, insn, record,
+ verbosity=Verbosity.NORMAL, indent=""):
+ return super().disassemble(field="LI",
+ insn=insn, record=record,
+ verbosity=verbosity, indent=indent)
+
+
+class TargetAddrOperandBD(TargetAddrOperand):
+ def span(self, record):
+ return record.fields["BD"]
+
+ def disassemble(self, insn, record,
+ verbosity=Verbosity.NORMAL, indent=""):
+ return super().disassemble(field="BD",
+ insn=insn, record=record,
+ verbosity=verbosity, indent=indent)
+
+
+class DOperandDX(SignedOperand):
+ def span(self, record):
+ operands = map(DynamicOperand, ("d0", "d1", "d2"))
+ spans = map(lambda operand: operand.span(record=record), operands)
+ return sum(spans, tuple())
+
+ def disassemble(self, insn, record,
+ verbosity=Verbosity.NORMAL, indent=""):
+ span = self.span(record=record)
+ if isinstance(insn, SVP64Instruction):
+ span = tuple(map(lambda bit: (bit + 32), span))
+ value = insn[span]
+
+ if verbosity >= Verbosity.VERBOSE:
+ yield f"{indent}D"
+ mapping = {
+ "d0": "[0:9]",
+ "d1": "[10:15]",
+ "d2": "[16]",
+ }
+ for (subname, subspan) in mapping.items():
+ operand = DynamicOperand(name=subname)
+ span = operand.span(record=record)
+ if isinstance(insn, SVP64Instruction):
+ span = tuple(map(lambda bit: (bit + 32), span))
+ value = insn[span]
+ span = map(str, span)
+ yield f"{indent}{indent}{operand.name} = D{subspan}"
+ yield f"{indent}{indent}{indent}{int(value):0{value.bits}b}"
+ yield f"{indent}{indent}{indent}{', '.join(span)}"
+ else:
+ yield str(value.to_signed_int())
+
+
+class Operands(tuple):
+ def __new__(cls, insn, iterable):
+ custom_insns = {
+ "b": {"target_addr": TargetAddrOperandLI},
+ "ba": {"target_addr": TargetAddrOperandLI},
+ "bl": {"target_addr": TargetAddrOperandLI},
+ "bla": {"target_addr": TargetAddrOperandLI},
+ "bc": {"target_addr": TargetAddrOperandBD},
+ "bca": {"target_addr": TargetAddrOperandBD},
+ "bcl": {"target_addr": TargetAddrOperandBD},
+ "bcla": {"target_addr": TargetAddrOperandBD},
+ "addpcis": {"D": DOperandDX},
+ "fishmv": {"D": DOperandDX},
+ "fmvis": {"D": DOperandDX},
+ }
+ custom_fields = {
+ "SVi": NonZeroOperand,
+ "SVd": NonZeroOperand,
+ "SVxd": NonZeroOperand,
+ "SVyd": NonZeroOperand,
+ "SVzd": NonZeroOperand,
+ "BD": SignedOperand,
+ "D": SignedOperand,
+ "DQ": SignedOperand,
+ "DS": SignedOperand,
+ "SI": SignedOperand,
+ "IB": SignedOperand,
+ "LI": SignedOperand,
+ "SIM": SignedOperand,
+ "SVD": SignedOperand,
+ "SVDS": SignedOperand,