Commit 8fb468bd authored by Kunshan Wang's avatar Kunshan Wang

Map IR Builder functions to comminsts.

Now the IR Builder API is also available as common instructions. We keep
muapi.h as the canonical definition, and the semantics of common
instructions maps to that of the API functions.
parent 1c61d81a
This diff is collapsed.
This diff is collapsed.
......@@ -18,10 +18,10 @@ text = sys.stdin.read()
for opcode, name in pat.findall(text):
macro_name = "MU_CI_" + name.upper().replace(".", "_")
opcode = opcode.upper()
opcode = opcode.lower()
defs.append((macro_name, opcode))
longest = max(longest, len(macro_name))
for macro_name, opcode in defs:
print("#define {} {}".format(macro_name.ljust(longest), opcode))
print("#define {} ((MuCommInst){})".format(macro_name.ljust(longest), opcode))
import re
from typing import List, Union, Tuple, Any, Callable, TypeVar
from typing.re import Pattern
Predicate = Union[str,
Tuple[Pattern, ...],
Callable[[Any], bool]]
def _string_contains(line, string):
return string in line
def _pattern_value_match(line, tup):
pat = tup[0]
vals = tup[1:]
m = pat.search(line)
return m is not None and all(
v is None or g == v
for g,v in zip(m.groups(), vals))
def _apply_func(line, func):
return func(line)
def find_line(lines: List[str], substr: Predicate, start: int = 0) -> int:
"""Find the line that contains or matches substr since line ``start``. """
if isinstance(substr, str):
pred = _string_contains
elif isinstance(substr, tuple):
pred = _pattern_value_match
else:
pred = _apply_func
for i in range(start, len(lines)):
if pred(lines[i], substr):
return i
raise KeyError("Not found: " + str(substr) + "\n text:" + str(lines) )
def extract_lines(parent: str, begin: Predicate, end: Predicate) -> str:
"""
Extract the lines between the line containing ``begin`` and the line
containing ``end`` (excluding both lines) in ``parent``.
"""
lines = parent.splitlines()
begin_line = find_line(lines, begin)
end_line = find_line(lines, end, begin_line+1)
new_lines = lines[begin_line+1:end_line]
return "\n".join(new_lines)
def inject_lines(parent: str, begin: Predicate, end: Predicate, generated: str) -> str:
"""
Replace the lines between the line containing ``begin`` and the line
containing ``end`` (excluding both lines) in ``parent`` with ``generated``.
"""
lines = parent.splitlines()
begin_line = find_line(lines, begin)
end_line = find_line(lines, end, begin_line+1)
new_lines = lines[:begin_line+1] + generated.splitlines() + lines[end_line:]
return "\n".join(new_lines)
"""
Read muapi.h and write common instruction definitions in reStructuredText.
Usage: python3 scripts/muapi-irbuilder-to-comminsts.py < muapi.h
Then paste into common-insts.rst
"""
import muapiparser
import sys
start_id_comminst = 0x300
start_id_constant = 0x400
_type_map = {
"void" : "",
"MuID" : "int<32>",
"MuName" : "iref<int<8>>",
"MuBool" : "int<32>",
"MuWPID" : "int<32>",
"MuArraySize" : "int<64>",
"MuBinOptr" : "int<32>",
"MuCmpOptr" : "int<32>",
"MuConvOptr" : "int<32>",
"MuDestKind" : "int<32>",
"MuMemOrd" : "int<32>",
"MuAtomicRMWOptr" : "int<32>",
"MuCallConv" : "int<32>",
"MuCommInst" : "int<32>",
"MuFlag" : "int<32>",
"int" : "int<32>",
"long" : "int<64>",
"int8_t" : "int<8>",
"uint8_t" : "int<8>",
"int16_t" : "int<16>",
"uint16_t" : "int<16>",
"int32_t" : "int<32>",
"uint32_t" : "int<32>",
"int64_t" : "int<64>",
"uint64_t" : "int<64>",
"intptr_t" : "int<64>",
"uintptr_t" : "int<64>",
"float" : "float",
"double" : "double",
}
def to_mu_ty(cty):
if cty.endswith("*"):
return "iref<{}>".format(to_mu_ty(cty[:-1]))
elif cty.startswith("Mu") and cty.endswith("Node"):
return "irnoderef"
elif cty in _type_map:
return _type_map[cty]
else:
raise Exception("I don't know how to translate: {}".format(cty))
def print_comminsts(ast):
muctx_methods = [s["methods"] for s in ast["structs"]
if s["name"] == "MuCtx"][0]
index_new_bundle = 0
while muctx_methods[index_new_bundle]["name"] != "new_bundle":
index_new_bundle += 1
next_id = start_id_comminst
for i in range(index_new_bundle, len(muctx_methods)):
meth = muctx_methods[i]
name = meth["name"]
params = meth["params"]
ret_ty = meth["ret_ty"]
mu_params = []
for param in params[1:]: # skip MuCtx*
pn = param["name"]
pt = param["type"]
mpn = "%" + pn
mpt = to_mu_ty(pt)
mu_params.append("{}: {}".format(mpn, mpt))
mu_params_joined = ", ".join(mu_params)
mu_ret_ty = to_mu_ty(ret_ty)
print(" [0x{:x}]@uvm.irbuilder.{} ({}) -> ({})".format(
next_id, name, mu_params_joined, mu_ret_ty))
next_id += 1
_enums = [
"MuDestKind",
"MuBinOptr",
"MuCmpOptr",
"MuConvOptr",
"MuMemOrd",
"MuAtomicRMWOptr",
"MuCallConv",
"MuCommInst",
]
def print_constants(ast):
""" NOT USED """
enums = ast["enums"]
next_id = start_id_constant
enums_map = {}
for enum in enums:
enums_map[enum["name"]] = enum["defs"]
print(" .typedef @uvm.irbuilder.MuFlag = int<32> // Private. Not available for the client.")
for enum_name in _enums:
defs = enums_map[enum_name]
for def_ in defs:
cn = def_["name"]
cv = def_["value"]
mcn = "@uvm.irbuilder." + cn
mcv = cv
print(" .const {} <@uvm.irbuilder.MuFlag> = {} // ID: 0x{:x}".format(
mcn, mcv, next_id))
next_id += 1
def main():
txt = sys.stdin.read()
ast = muapiparser.parse_muapi(txt)
print_comminsts(ast)
#print()
#print_constants(ast) # Do not print. This merely pollutes the pre-loaded
# space with more constants, and not profitable.
# We keep muapi.h as the canonical definition.
# Clients should define their own constants.
if __name__=='__main__':
main()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment