2 import argparse
as _argparse
3 import codecs
as _codecs
4 import dataclasses
as _dataclasses
6 import pathlib
as _pathlib
10 from openpower
.decoder
.power_enums
import (
16 CROutSel
as _CROutSel
,
24 return map(lambda string
: (" " + string
), strings
)
30 def c_decl(self
, name
):
34 def c_value(self
, prefix
="", suffix
=""):
39 def c_var(self
, name
):
43 class Enum(Field
, _enum
.Enum
):
46 c_tag
= f
"svp64_{cls.__name__.lower()}"
47 yield f
"enum {c_tag} {{"
49 yield from indent(item
.c_value(suffix
=","))
52 def c_value(self
, prefix
="", suffix
=""):
53 c_tag
= f
"svp64_{self.__class__.__name__.lower()}"
54 yield f
"{prefix}{c_tag.upper()}_{self.name.upper()}{suffix}"
58 c_tag
= f
"svp64_{cls.__name__.lower()}"
59 yield f
"enum {c_tag} {name};"
62 # Python forbids inheriting from enum unless it's empty.
63 In1Sel
= Enum("In1Sel", {item
.name
:item
.value
for item
in _In1Sel
})
64 In2Sel
= Enum("In2Sel", {item
.name
:item
.value
for item
in _In2Sel
})
65 In3Sel
= Enum("In3Sel", {item
.name
:item
.value
for item
in _In3Sel
})
66 OutSel
= Enum("OutSel", {item
.name
:item
.value
for item
in _OutSel
})
67 CRInSel
= Enum("CRInSel", {item
.name
:item
.value
for item
in _CRInSel
})
68 CROutSel
= Enum("CROutSel", {item
.name
:item
.value
for item
in _CROutSel
})
69 SVPType
= Enum("SVPType", {item
.name
:item
.value
for item
in _SVPtype
})
70 SVEType
= Enum("SVEType", {item
.name
:item
.value
for item
in _SVEtype
})
71 SVEXTRA
= Enum("SVEXTRA", {item
.name
:item
.value
for item
in _SVEXTRA
})
74 class Opcode(Field
, str):
75 def c_value(self
, prefix
="", suffix
=""):
76 yield f
"{prefix}\"{self}\"{suffix}"
80 yield f
"const char *{name};"
83 class Name(Field
, str):
85 escaped
= self
.replace("\"", "\\\"")
86 return f
"\"{escaped}\""
88 def c_value(self
, prefix
="", suffix
=""):
89 yield f
"{prefix}{self!r}{suffix}"
93 yield f
"const char *{name};"
96 @_dataclasses.dataclass(eq
=True, frozen
=True)
119 yield f
"struct svp64_entry {{"
120 for field
in _dataclasses
.fields(cls
):
121 if issubclass(field
.type, Enum
):
122 bits
= len(field
.type).bit_length()
123 yield from indent([f
"uint64_t {field.name} : {bits};"])
125 yield from indent(field
.type.c_var(name
=field
.name
))
128 def c_value(self
, prefix
="", suffix
=""):
130 for field
in _dataclasses
.fields(self
):
132 attr
= getattr(self
, name
)
133 yield from indent(attr
.c_value(prefix
=f
".{name} = ", suffix
=","))
137 def c_var(cls
, name
):
138 yield f
"struct svp64_entry {name};"
141 class Codegen(_enum
.Enum
):
142 PPC_OPC_SVP64_H
= _enum
.auto()
143 PPC_OPC_SVP64_C
= _enum
.auto()
146 def _missing_(cls
, value
):
148 "ppc-opc-svp64.h": Codegen
.PPC_OPC_SVP64_H
,
149 "ppc-opc-svp64.c": Codegen
.PPC_OPC_SVP64_C
,
154 Codegen
.PPC_OPC_SVP64_H
: "ppc-opc-svp64.h",
155 Codegen
.PPC_OPC_SVP64_C
: "ppc-opc-svp64.c",
158 def generate(self
, entries
):
159 def ppc_opc_svp64_h(entries
):
162 def ppc_opc_svp64_c(entries
):
166 Codegen
.PPC_OPC_SVP64_H
: ppc_opc_svp64_h
,
167 Codegen
.PPC_OPC_SVP64_C
: ppc_opc_svp64_c
,
171 def regex_enum(enum
):
172 assert issubclass(enum
, _enum
.Enum
)
173 return "|".join(item
.name
for item
in enum
)
176 PATTERN_VHDL_BINARY
= r
"(?:2#[01]+#)"
177 PATTERN_DECIMAL
= r
"(?:[0-9]+)"
178 PATTERN_PARTIAL_BINARY
= r
"(?:[01-]+)"
180 # Examples of the entries to be caught by the pattern below:
181 # 2 => (P2, EXTRA3, RA_OR_ZERO, NONE, NONE, RT, NONE, NONE, NONE, Idx1, NONE, NONE, Idx0, NONE, NONE, NONE), -- lwz
182 # -----10110 => (P2, EXTRA3, NONE, FRB, NONE, FRT, NONE, NONE, CR1, NONE, Idx1, NONE, Idx0, NONE, NONE, Idx0), -- fsqrts
183 # 2#0000000000# => (P2, EXTRA3, NONE, NONE, NONE, NONE, NONE, BFA, BF, NONE, NONE, NONE, NONE, NONE, Idx1, Idx0), -- mcrf
186 rf
"(?P<opcode>{PATTERN_VHDL_BINARY}|{PATTERN_DECIMAL}|{PATTERN_PARTIAL_BINARY})",
190 rf
"(?P<ptype>{regex_enum(_SVPtype)})",
191 rf
"(?P<etype>{regex_enum(_SVEtype)})",
192 rf
"(?P<in1>{regex_enum(_In1Sel)})",
193 rf
"(?P<in2>{regex_enum(_In2Sel)})",
194 rf
"(?P<in3>{regex_enum(_In3Sel)})",
195 rf
"(?P<out>{regex_enum(_OutSel)})",
196 rf
"(?P<out2>{regex_enum(_OutSel)})",
197 rf
"(?P<cr_in>{regex_enum(_CRInSel)})",
198 rf
"(?P<cr_out>{regex_enum(_CROutSel)})",
199 rf
"(?P<sv_in1>{regex_enum(_SVEXTRA)})",
200 rf
"(?P<sv_in2>{regex_enum(_SVEXTRA)})",
201 rf
"(?P<sv_in3>{regex_enum(_SVEXTRA)})",
202 rf
"(?P<sv_out>{regex_enum(_SVEXTRA)})",
203 rf
"(?P<sv_out2>{regex_enum(_SVEXTRA)})",
204 rf
"(?P<sv_cr_in>{regex_enum(_SVEXTRA)})",
205 rf
"(?P<sv_cr_out>{regex_enum(_SVEXTRA)})",
210 r
"(?P<name>[A-Za-z0-9_\./]+)",
213 REGEX
= _re
.compile(PATTERN
)
218 match
= REGEX
.match(line
)
219 if match
is not None:
220 entry
= match
.groupdict()
221 for field
in _dataclasses
.fields(Entry
):
224 if issubclass(field
.type, _enum
.Enum
):
225 value
= {item
.name
:item
for item
in field
.type}[value
]
227 value
= field
.type(value
)
233 entries
= tuple(parse(_sys
.stdin
))
234 for line
in codegen
.generate(entries
):
238 if __name__
== "__main__":
239 parser
= _argparse
.ArgumentParser()
240 parser
.add_argument("codegen", type=Codegen
, choices
=Codegen
, help="code generator")
242 args
= vars(parser
.parse_args())