import abc as _abc
import argparse as _argparse
-import codecs as _codecs
-import csv as _csv
import dataclasses as _dataclasses
import enum as _enum
-import pathlib as _pathlib
import re as _re
-import sys as _sys
from openpower.decoder.power_enums import (
In1Sel as _In1Sel,
return map(lambda string: (" " + string), strings)
-class Field:
+class CType:
@classmethod
@_abc.abstractmethod
def c_decl(self, name):
pass
-class Enum(Field, _enum.Enum):
+class Enum(CType, _enum.Enum):
@classmethod
def c_decl(cls):
c_tag = f"svp64_{cls.__name__.lower()}"
@classmethod
def c_var(cls, name):
c_tag = f"svp64_{cls.__name__.lower()}"
- yield f"enum {c_tag} {name};"
+ yield f"enum {c_tag} {name}"
# Python forbids inheriting from enum unless it's empty.
SVEXTRA = Enum("SVEXTRA", {item.name:item.value for item in _SVEXTRA})
-class Opcode(Field):
+class Opcode(CType):
def __init__(self, value, mask, bits):
self.__value = value
self.__mask = mask
def c_value(self, prefix="", suffix=""):
yield f"{prefix}{{"
yield from indent([
- f".value = {self.value},",
- f".mask = {self.mask},",
+ f".value = UINT32_C(0x{self.value:08X}),",
+ f".mask = UINT32_C(0x{self.mask:08X}),",
])
yield f"}}{suffix}"
@classmethod
def c_var(cls, name):
- yield f"struct svp64_opcode {name};"
+ yield f"struct svp64_opcode {name}"
class IntegerOpcode(Opcode):
return super().__init__(value=value, mask=mask, bits=bits)
-class Name(Field, str):
+class Name(CType, str):
def __repr__(self):
escaped = self.replace("\"", "\\\"")
return f"\"{escaped}\""
@classmethod
def c_var(cls, name):
- yield f"const char *{name};"
+ yield f"const char *{name}"
@_dataclasses.dataclass(eq=True, frozen=True)
-class Entry:
+class Entry(CType):
name: Name
opcode: Opcode
in1: In1Sel
sv_cr_in: SVEXTRA
sv_cr_out: SVEXTRA
+ def __lt__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return self.name < other.name
+
@classmethod
def c_decl(cls):
+ bits_all = 0
yield f"struct svp64_entry {{"
for field in _dataclasses.fields(cls):
if issubclass(field.type, Enum):
bits = len(field.type).bit_length()
yield from indent([f"uint64_t {field.name} : {bits};"])
+ bits_all += bits
else:
- yield from indent(field.type.c_var(name=field.name))
+ yield from indent(field.type.c_var(name=f"{field.name};"))
+ bits_rsvd = (64 - (bits_all % 64))
+ if bits_rsvd:
+ yield from indent([f"uint64_t : {bits_rsvd};"])
yield f"}};"
def c_value(self, prefix="", suffix=""):
@classmethod
def c_var(cls, name):
- yield f"struct svp64_entry {name};"
+ yield f"struct svp64_entry {name}"
class Codegen(_enum.Enum):
yield f"#define {self.name}"
yield ""
+ yield "#include <stdint.h>"
+ yield ""
+
+ yield from Opcode.c_decl()
+ yield ""
+
enums = (
- SVPType, SVEType,
In1Sel, In2Sel, In3Sel, OutSel,
CRInSel, CROutSel,
- SVEXTRA,
+ SVPType, SVEType, SVEXTRA,
)
for enum in enums:
yield from enum.c_decl()
yield ""
- yield from Opcode.c_decl()
+ yield from Entry.c_decl()
yield ""
- yield from Entry.c_decl()
+ yield "extern const struct svp64_entry svp64_entries[];"
+ yield "extern const unsigned int svp64_num_entries;"
yield ""
yield f"#endif /* {self.name} */"
yield ""
def ppc_opc_svp64_c(entries):
- yield from ()
+ yield from DISCLAIMER
+ yield ""
+
+ yield "#include \"ppc-opc-svp64.h\""
+ yield ""
+
+ yield "const struct svp64_entry svp64_entries[] = {{"
+ for (index, entry) in enumerate(entries):
+ yield from indent(entry.c_value(prefix=f"[{index}] = ", suffix=","))
+ yield f"}};"
+ yield f"const unsigned int svp64_num_entries = {len(entries)};"
+ yield ""
return {
Codegen.PPC_OPC_SVP64_H: ppc_opc_svp64_h,
def parse(path, opcode_cls):
for entry in ISA.get_svp64_csv(path):
# skip instructions that are not suitable
- name = entry["name"] = entry.pop("comment")
+ name = entry["name"] = entry.pop("comment").split("=")[-1]
if name.startswith("l") and name.endswith("br"):
continue
if name in {"mcrxr", "mcrxrx", "darn"}:
}
for (path, opcode_cls) in table.items():
entries.extend(parse(path, opcode_cls))
+ entries = sorted(frozenset(entries))
for line in codegen.generate(entries):
print(line)