X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fopenpower%2Fsv%2Fsv_binutils.py;h=b4dea0acf62ed1419fb36cda661c99f2b702d3ee;hb=b1bb73777b241c9f77059b6a9e6828b5571757be;hp=a920e6145f8dbe9a63e6472b9fba444b52cc4955;hpb=dc41f2c05a6bb21f7668582234f21e0523d10597;p=openpower-isa.git diff --git a/src/openpower/sv/sv_binutils.py b/src/openpower/sv/sv_binutils.py index a920e614..b4dea0ac 100644 --- a/src/openpower/sv/sv_binutils.py +++ b/src/openpower/sv/sv_binutils.py @@ -13,11 +13,12 @@ from openpower.decoder.power_enums import ( In3Sel as _In3Sel, OutSel as _OutSel, CRInSel as _CRInSel, + CRIn2Sel as _CRIn2Sel, CROutSel as _CROutSel, - SVPtype as _SVPtype, - SVEtype as _SVEtype, + SVPType as _SVPType, + SVEType as _SVEType, SVExtra as _SVExtra, - Function as _Function, + SVMode as _SVMode, find_wiki_dir as _find_wiki_dir, ) from openpower.consts import SVP64MODE as _SVP64MODE @@ -178,11 +179,12 @@ In2Sel = Enum("In2Sel", _In2Sel, c_tag="svp64_in2_sel") In3Sel = Enum("In3Sel", _In3Sel, c_tag="svp64_in3_sel") OutSel = Enum("OutSel", _OutSel, c_tag="svp64_out_sel") CRInSel = Enum("CRInSel", _CRInSel, c_tag="svp64_cr_in_sel") +CRIn2Sel = Enum("CRIn2Sel", _CRIn2Sel, c_tag="svp64_cr_in2_sel") CROutSel = Enum("CROutSel", _CROutSel, c_tag="svp64_cr_out_sel") -PType = Enum("PType", _SVPtype, c_tag="svp64_ptype") -EType = Enum("EType", _SVEtype, c_tag="svp64_etype", exclude="NONE") +PType = Enum("PType", _SVPType, c_tag="svp64_ptype") +EType = Enum("EType", _SVEType, c_tag="svp64_etype", exclude="NONE") Extra = Enum("Extra", _SVExtra, c_tag="svp64_extra", exclude="Idx_1_2") -Function = Enum("Function", _Function, c_tag="svp64_function") +Mode = Enum("Mode", _SVMode, c_tag="svp64_mode") class Constant(_enum.Enum, metaclass=EnumMeta): @@ -199,7 +201,7 @@ class Constant(_enum.Enum, metaclass=EnumMeta): yield f"{prefix}{self.c_tag.upper()}_{self.c_name.upper()}{suffix}" -Mode = Constant("Mode", _SVP64MODE) +ModeConst = Constant("Mode", _SVP64MODE) class StructMeta(ObjectMeta): @@ -318,7 +320,7 @@ class Instruction(Struct, c_tag="svp64_insn"): yield from super().c_decl() yield "" - for (path, field) in _SVP64Instruction.traverse(): + for (path, field) in _SVP64Instruction.traverse(path=""): yield from getter(path, field) yield from setter(path, field) @@ -336,43 +338,60 @@ class Name(Object, str, c_typedef="const char *"): return f"{prefix}const char *{name}{suffix}" -@_dataclasses.dataclass(eq=True, frozen=True) -class Opcode(Struct): - class Value(UInt32): - def __new__(cls, value): - if isinstance(value, int): - value = f"0x{value:08x}" - return super().__new__(cls, value) +class BooleanMeta(ObjectMeta): + def __len__(cls): + return 1 - class Mask(UInt32): - def __new__(cls, value): - if isinstance(value, int): - value = f"0x{value:08x}" - return super().__new__(cls, value) - value: Value - mask: Mask +class Boolean(Object, metaclass=BooleanMeta): + def __init__(self, value): + self.__state = bool(value) + return super().__init__() + + def __bool__(self): + return self.__state + + def __repr__(self): + return self.__state.__repr__() + + @property + def name(self): + return "true" if self else "false" + + @property + def value(self): + return "true" if self else "false" + + def c_value(self, *, prefix="", suffix="", **kwargs): + yield f"{prefix}{self.value}{suffix}" + + @classmethod + def c_var(cls, name, prefix="", suffix=""): + return f"{prefix}bool {name}{suffix}" @_dataclasses.dataclass(eq=True, frozen=True) class Desc(Struct): - function: Function + mode: Mode in1: In1Sel in2: In2Sel in3: In3Sel out: OutSel out2: OutSel cr_in: CRInSel + cr_in2: CRIn2Sel cr_out: CROutSel - sv_ptype: PType - sv_etype: EType - sv_in1: Extra - sv_in2: Extra - sv_in3: Extra - sv_out: Extra - sv_out2: Extra - sv_cr_in: Extra - sv_cr_out: Extra + ptype: PType + etype: EType + extra_idx_in1: Extra + extra_idx_in2: Extra + extra_idx_in3: Extra + extra_idx_out: Extra + extra_idx_out2: Extra + extra_idx_cr_in: Extra + extra_idx_cr_in2: Extra + extra_idx_cr_out: Extra + Rc: Boolean @classmethod def c_decl(cls): @@ -388,11 +407,50 @@ class Desc(Struct): yield f"}};" +@_dataclasses.dataclass(eq=True, frozen=True) +class Opcode(Struct): + class Value(UInt32): + def __new__(cls, value): + if isinstance(value, int): + value = f"0x{value:08x}" + return super().__new__(cls, value) + + class Mask(UInt32): + def __new__(cls, value): + if isinstance(value, int): + value = f"0x{value:08x}" + return super().__new__(cls, value) + + value: Value + mask: Mask + + +class Opcodes(Object, c_typedef="const struct svp64_opcode *"): + def __init__(self, offset): + self.__offset = offset + return super().__init__() + + def __repr__(self): + return f"{self.__class__.__name__}({self.__offset})" + + @classmethod + def c_var(cls, name, prefix="", suffix=""): + return f"{prefix}{cls.c_typedef}{name}{suffix}" + + @classmethod + def c_decl(cls): + yield "const struct svp64_opcode *opcodes;" + + def c_value(self, *, prefix="", suffix="", **kwargs): + yield f"{prefix}&svp64_opcodes[{self.__offset}]{suffix}" + + @_dataclasses.dataclass(eq=True, frozen=True) class Record(Struct): name: Name - opcode: Opcode desc: Desc + opcodes: Opcodes + nr_opcodes: Size def __lt__(self, other): if not isinstance(other, self.__class__): @@ -408,8 +466,8 @@ class Codegen(_enum.Enum): def __str__(self): return self.value - def generate(self, records): - def ppc_svp64_h(records, num_records): + def generate(self, opcodes, records): + def ppc_svp64_h(opcodes, nr_opcodes, records, nr_records): disclaimer = DISCLAIMER.format(path=str(self), desc="Header file for PowerPC opcode table (SVP64 extensions)") yield from disclaimer.splitlines() @@ -429,9 +487,9 @@ class Codegen(_enum.Enum): enums = ( In1Sel, In2Sel, In3Sel, OutSel, - CRInSel, CROutSel, + CRInSel, CRIn2Sel, CROutSel, PType, EType, Extra, - Mode, Function, + Mode, ModeConst, ) for enum in enums: yield from enum.c_decl() @@ -441,9 +499,15 @@ class Codegen(_enum.Enum): yield from cls.c_decl() yield "" + yield opcodes.c_var("svp64_opcodes", + prefix="extern const ", suffix=";") + yield nr_opcodes.c_var("svp64_nr_opcodes", + prefix="extern const ", suffix=";") + yield "" + yield records.c_var("svp64_records", prefix="extern const ", suffix=";") - yield num_records.c_var("svp64_num_records", + yield nr_records.c_var("svp64_nr_records", prefix="extern const ", suffix=";") yield "" @@ -458,12 +522,13 @@ class Codegen(_enum.Enum): yield f"#endif /* {self.name} */" - def ppc_svp64_opc_c(records, num_records): + def ppc_svp64_opc_c(opcodes, nr_opcodes, records, nr_records): disclaimer = DISCLAIMER.format(path=str(self), desc="PowerPC opcode list (SVP64 extensions)") yield from disclaimer.splitlines() yield "" + yield "#include " yield "#include \"opcode/ppc-svp64.h\"" yield "" @@ -513,26 +578,40 @@ class Codegen(_enum.Enum): OutSel.RT_OR_ZERO: "RT", OutSel.FRT: "FRT", OutSel.FRS: "FRS", + OutSel.RS: "RS", }) yield from opindex(CRInSel, "cr_in", { CRInSel.BI: "BI", CRInSel.BFA: "BFA", CRInSel.BC: "BC", + CRInSel.BA: "BA", CRInSel.WHOLE_REG: "FXM", }) + yield from opindex(CRIn2Sel, "cr_in2", { + CRIn2Sel.BB: "BB", + }) yield from opindex(CROutSel, "cr_out", { CROutSel.BF: "BF", CROutSel.BT: "BT", CROutSel.WHOLE_REG: "FXM", }) + yield opcodes.c_var("svp64_opcodes", + prefix="const ", suffix=" = \\") + yield from opcodes.c_value(prefix="", suffix=";") + yield "" + yield nr_opcodes.c_var("svp64_nr_opcodes", + prefix="const ", suffix=" = \\") + yield from indent(nr_opcodes.c_value(suffix=";")) + yield "" + yield records.c_var("svp64_records", prefix="const ", suffix=" = \\") yield from records.c_value(prefix="", suffix=";") yield "" - yield num_records.c_var("svp64_num_records", + yield nr_records.c_var("svp64_nr_records", prefix="const ", suffix=" = \\") - yield from indent(num_records.c_value(suffix=";")) + yield from indent(nr_records.c_value(suffix=";")) yield "" yield "const struct powerpc_pd_reg svp64_regs[] = {" @@ -555,16 +634,21 @@ class Codegen(_enum.Enum): prefix="const ", suffix=" = \\") yield from indent(num_regs.c_value(suffix=";")) + opcodes = Array[Opcode, ...](opcodes) + nr_opcodes = Size("(sizeof (svp64_opcodes) / sizeof (svp64_opcodes[0]))") + records = Array[Record, ...](records) - num_records = Size("(sizeof (svp64_records) / sizeof (svp64_records[0]))") + nr_records = Size("(sizeof (svp64_records) / sizeof (svp64_records[0]))") yield from { Codegen.PPC_SVP64_GEN_H: ppc_svp64_h, Codegen.PPC_SVP64_OPC_GEN_C: ppc_svp64_opc_c, - }[self](records, num_records) + }[self](opcodes, nr_opcodes, records, nr_records) -def records(db): +def collect(db): + opcodes = [] + records = [] fields = {field.name:field.type for field in _dataclasses.fields(Desc)} for insn in filter(lambda insn: insn.svp64 is not None, db): @@ -573,12 +657,14 @@ def records(db): for (key, cls) in fields.items(): value = getattr(insn, key) - if (((cls is EType) and (value is _SVEtype.NONE)) or + if (((cls is EType) and (value is _SVEType.NONE)) or ((cls is Extra) and (value is _SVExtra.Idx_1_2))): desc = None break - if issubclass(cls, _enum.Enum): + if issubclass(cls, Boolean): + value = Boolean(value) + elif issubclass(cls, _enum.Enum): value = cls[value.name] else: value = cls(value) @@ -588,17 +674,25 @@ def records(db): continue name = Name(f"sv.{insn.name}") - value = Opcode.Value(insn.opcode.value) - mask = Opcode.Mask(insn.opcode.mask) - opcode = Opcode(value=value, mask=mask) + offset = len(opcodes) + for opcode in insn.opcodes: + value = Opcode.Value(opcode.value) + mask = Opcode.Mask(opcode.mask) + opcode = Opcode(value=value, mask=mask) + opcodes.append(opcode) desc = Desc(**desc) - yield Record(name=name, opcode=opcode, desc=desc) + record = Record(name=name, desc=desc, + opcodes=Opcodes(offset), nr_opcodes=Size(len(insn.opcodes))) + records.append(record) + + return (opcodes, records) def main(codegen): db = _Database(_find_wiki_dir()) - for line in codegen.generate(records(db)): + (opcodes, records) = collect(db) + for line in codegen.generate(opcodes, records): print(line)