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
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):
yield f"{prefix}{self.c_tag.upper()}_{self.c_name.upper()}{suffix}"
-Mode = Constant("Mode", _SVP64MODE)
+ModeConst = Constant("Mode", _SVP64MODE)
class StructMeta(ObjectMeta):
yield f"{mangle(path, 'get')}(const {cls.c_typedef} *insn)"
yield "{"
yield from indent(["uint64_t value = insn->value;"])
- yield ""
yield from indent(["return ("])
actions = []
for (dst, src) in enumerate(reversed(field)):
src = f"UINT64_C({src})"
action = f"(((value >> {src}) & UINT64_C(1)) << {dst})"
actions.append(action)
- for action in indent(indent(actions)):
+ for action in indent(indent(actions[:-1])):
yield f"{action} |"
- yield from indent(indent(["UINT64_C(0)"]))
+ yield from indent(indent([f"{actions[-1]}"]))
yield from indent([");"])
yield "}"
yield ""
action = f"(((value >> {src}) & UINT64_C(1)) << {dst})"
actions.append(action)
yield from indent(["insn->value |= ("])
- for action in indent(indent(actions)):
+ for action in indent(indent(actions[:-1])):
yield f"{action} |"
- yield from indent(indent(["UINT64_C(0)"]))
+ yield from indent(indent([f"{actions[-1]}"]))
yield from indent([");"])
yield "}"
yield ""
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)
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):
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__):
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()
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()
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 ""
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 <stdbool.h>"
yield "#include \"opcode/ppc-svp64.h\""
yield ""
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[] = {"
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):
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, Extra):
+ value = tuple(value)
+ if not value:
+ value = cls["NONE"]
+ else:
+ value = cls[value[0].name]
+ elif issubclass(cls, _enum.Enum):
value = cls[value.name]
else:
value = cls(value)
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)