mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-23 20:01:24 +00:00

This is an ongoing series of commits that are reformatting our Python code. Reformatting is done with `black`. If you end up having problems merging this commit because you have made changes to a python file, the best way to handle that is to run git checkout --ours <yourfile> and then reformat it with black. If you run into any problems, post to discourse about it and we will try to help. RFC Thread below: https://discourse.llvm.org/t/rfc-document-and-standardize-python-code-style Reviewed By: MatzeB Differential Revision: https://reviews.llvm.org/D150761
184 lines
5.0 KiB
Python
184 lines
5.0 KiB
Python
#!/usr/bin/env python3
|
|
|
|
# This script was committed on 20/11/2019 and it would probably make sense to remove
|
|
# it after the next release branches.
|
|
|
|
# This script is pipe based and converts an arm_neon.td (or arm_fp16.td) file
|
|
# using the old single-char type modifiers to an equivalent new-style form where
|
|
# each modifier is orthogonal and they can be composed.
|
|
#
|
|
# It was used to directly generate the .td files on main, so if you have any
|
|
# local additions I would suggest implementing any modifiers here, and running
|
|
# it over your entire pre-merge .td files rather than trying to resolve any
|
|
# conflicts manually.
|
|
|
|
import re, sys
|
|
|
|
MOD_MAP = {
|
|
"v": "v",
|
|
"x": "S",
|
|
"u": "U",
|
|
"d": ".",
|
|
"g": "q",
|
|
"j": "Q",
|
|
"w": ">Q",
|
|
"n": ">",
|
|
"h": "<",
|
|
"q": "<Q",
|
|
"e": "<U",
|
|
"m": "<q",
|
|
"i": "I",
|
|
"l": "IU>",
|
|
"s": "1",
|
|
"z": "1<",
|
|
"r": "1>",
|
|
"b": "1U",
|
|
"$": "1S",
|
|
"k": "Q",
|
|
"2": "2",
|
|
"3": "3",
|
|
"4": "4",
|
|
"B": "2Q",
|
|
"C": "3Q",
|
|
"D": "4Q",
|
|
"p": "*",
|
|
"c": "c*",
|
|
"7": "<<q",
|
|
"8": "<<",
|
|
"9": "<<Q",
|
|
"t": "p",
|
|
}
|
|
|
|
|
|
def typespec_elt_size(typespec):
|
|
if "c" in typespec:
|
|
return 8
|
|
elif "s" in typespec or "h" in typespec:
|
|
return 16
|
|
elif "i" in typespec or "f" in typespec:
|
|
return 32
|
|
elif "l" in typespec or "d" in typespec:
|
|
return 64
|
|
elif "k" in typespec:
|
|
return 128
|
|
|
|
|
|
def get_resize(cur, desired):
|
|
res = ""
|
|
while cur < desired:
|
|
res += ">"
|
|
cur *= 2
|
|
while cur > desired:
|
|
res += "<"
|
|
cur /= 2
|
|
return res
|
|
|
|
|
|
def remap_protocol(proto, typespec, name):
|
|
key_type = 0
|
|
|
|
# Conversions like to see the integer type so they know signedness.
|
|
if (
|
|
"vcvt" in name
|
|
and "_f" in name
|
|
and name != "vcvt_f32_f64"
|
|
and name != "vcvt_f64_f32"
|
|
):
|
|
key_type = 1
|
|
default_width = typespec_elt_size(typespec)
|
|
inconsistent_width = False
|
|
for elt in typespec:
|
|
new_width = typespec_elt_size(elt)
|
|
if new_width and new_width != default_width:
|
|
inconsistent_width = True
|
|
|
|
res = ""
|
|
for i, c in enumerate(proto):
|
|
# void and pointers make for bad discriminators in CGBuiltin.cpp.
|
|
if c in "vcp":
|
|
key_type += 1
|
|
|
|
if c in MOD_MAP:
|
|
cur_mod = MOD_MAP[c]
|
|
elif inconsistent_width:
|
|
# Otherwise it's a fixed output width modifier.
|
|
sys.stderr.write(
|
|
f"warning: {name} uses fixed output size but has inconsistent input widths: {proto} {typespec}\n"
|
|
)
|
|
|
|
if c == "Y":
|
|
# y: scalar of half float
|
|
resize = get_resize(default_width, 16)
|
|
cur_mod = f"1F{resize}"
|
|
elif c == "y":
|
|
# y: scalar of float
|
|
resize = get_resize(default_width, 32)
|
|
cur_mod = f"1F{resize}"
|
|
elif c == "o":
|
|
# o: scalar of double
|
|
resize = get_resize(default_width, 64)
|
|
cur_mod = f"1F{resize}"
|
|
elif c == "I":
|
|
# I: scalar of 32-bit signed
|
|
resize = get_resize(default_width, 32)
|
|
cur_mod = f"1S{resize}"
|
|
elif c == "L":
|
|
# L: scalar of 64-bit signed
|
|
resize = get_resize(default_width, 64)
|
|
cur_mod = f"1S{resize}"
|
|
elif c == "U":
|
|
# I: scalar of 32-bit unsigned
|
|
resize = get_resize(default_width, 32)
|
|
cur_mod = f"1U{resize}"
|
|
elif c == "O":
|
|
# O: scalar of 64-bit unsigned
|
|
resize = get_resize(default_width, 64)
|
|
cur_mod = f"1U{resize}"
|
|
elif c == "f":
|
|
# f: float (int args)
|
|
resize = get_resize(default_width, 32)
|
|
cur_mod = f"F{resize}"
|
|
elif c == "F":
|
|
# F: double (int args)
|
|
resize = get_resize(default_width, 64)
|
|
cur_mod = f"F{resize}"
|
|
elif c == "H":
|
|
# H: half (int args)
|
|
resize = get_resize(default_width, 16)
|
|
cur_mod = f"F{resize}"
|
|
elif c == "0":
|
|
# 0: half (int args), ignore 'Q' size modifier.
|
|
resize = get_resize(default_width, 16)
|
|
cur_mod = f"Fq{resize}"
|
|
elif c == "1":
|
|
# 1: half (int args), force 'Q' size modifier.
|
|
resize = get_resize(default_width, 16)
|
|
cur_mod = f"FQ{resize}"
|
|
|
|
if len(cur_mod) == 0:
|
|
raise Exception(f"WTF: {c} in {name}")
|
|
|
|
if key_type != 0 and key_type == i:
|
|
cur_mod += "!"
|
|
|
|
if len(cur_mod) == 1:
|
|
res += cur_mod
|
|
else:
|
|
res += "(" + cur_mod + ")"
|
|
|
|
return res
|
|
|
|
|
|
def replace_insts(m):
|
|
start, end = m.span("proto")
|
|
start -= m.start()
|
|
end -= m.start()
|
|
new_proto = remap_protocol(m["proto"], m["kinds"], m["name"])
|
|
return m.group()[:start] + new_proto + m.group()[end:]
|
|
|
|
|
|
INST = re.compile(r'Inst<"(?P<name>.*?)",\s*"(?P<proto>.*?)",\s*"(?P<kinds>.*?)"')
|
|
|
|
new_td = INST.sub(replace_insts, sys.stdin.read())
|
|
sys.stdout.write(new_td)
|