184 lines · python
1#!/usr/bin/env python32 3# This script was committed on 20/11/2019 and it would probably make sense to remove4# it after the next release branches.5 6# This script is pipe based and converts an arm_neon.td (or arm_fp16.td) file7# using the old single-char type modifiers to an equivalent new-style form where8# each modifier is orthogonal and they can be composed.9#10# It was used to directly generate the .td files on main, so if you have any11# local additions I would suggest implementing any modifiers here, and running12# it over your entire pre-merge .td files rather than trying to resolve any13# conflicts manually.14 15import re, sys16 17MOD_MAP = {18 "v": "v",19 "x": "S",20 "u": "U",21 "d": ".",22 "g": "q",23 "j": "Q",24 "w": ">Q",25 "n": ">",26 "h": "<",27 "q": "<Q",28 "e": "<U",29 "m": "<q",30 "i": "I",31 "l": "IU>",32 "s": "1",33 "z": "1<",34 "r": "1>",35 "b": "1U",36 "$": "1S",37 "k": "Q",38 "2": "2",39 "3": "3",40 "4": "4",41 "B": "2Q",42 "C": "3Q",43 "D": "4Q",44 "p": "*",45 "c": "c*",46 "7": "<<q",47 "8": "<<",48 "9": "<<Q",49 "t": "p",50}51 52 53def typespec_elt_size(typespec):54 if "c" in typespec:55 return 856 elif "s" in typespec or "h" in typespec:57 return 1658 elif "i" in typespec or "f" in typespec:59 return 3260 elif "l" in typespec or "d" in typespec:61 return 6462 elif "k" in typespec:63 return 12864 65 66def get_resize(cur, desired):67 res = ""68 while cur < desired:69 res += ">"70 cur *= 271 while cur > desired:72 res += "<"73 cur /= 274 return res75 76 77def remap_protocol(proto, typespec, name):78 key_type = 079 80 # Conversions like to see the integer type so they know signedness.81 if (82 "vcvt" in name83 and "_f" in name84 and name != "vcvt_f32_f64"85 and name != "vcvt_f64_f32"86 ):87 key_type = 188 default_width = typespec_elt_size(typespec)89 inconsistent_width = False90 for elt in typespec:91 new_width = typespec_elt_size(elt)92 if new_width and new_width != default_width:93 inconsistent_width = True94 95 res = ""96 for i, c in enumerate(proto):97 # void and pointers make for bad discriminators in CGBuiltin.cpp.98 if c in "vcp":99 key_type += 1100 101 if c in MOD_MAP:102 cur_mod = MOD_MAP[c]103 elif inconsistent_width:104 # Otherwise it's a fixed output width modifier.105 sys.stderr.write(106 f"warning: {name} uses fixed output size but has inconsistent input widths: {proto} {typespec}\n"107 )108 109 if c == "Y":110 # y: scalar of half float111 resize = get_resize(default_width, 16)112 cur_mod = f"1F{resize}"113 elif c == "y":114 # y: scalar of float115 resize = get_resize(default_width, 32)116 cur_mod = f"1F{resize}"117 elif c == "o":118 # o: scalar of double119 resize = get_resize(default_width, 64)120 cur_mod = f"1F{resize}"121 elif c == "I":122 # I: scalar of 32-bit signed123 resize = get_resize(default_width, 32)124 cur_mod = f"1S{resize}"125 elif c == "L":126 # L: scalar of 64-bit signed127 resize = get_resize(default_width, 64)128 cur_mod = f"1S{resize}"129 elif c == "U":130 # I: scalar of 32-bit unsigned131 resize = get_resize(default_width, 32)132 cur_mod = f"1U{resize}"133 elif c == "O":134 # O: scalar of 64-bit unsigned135 resize = get_resize(default_width, 64)136 cur_mod = f"1U{resize}"137 elif c == "f":138 # f: float (int args)139 resize = get_resize(default_width, 32)140 cur_mod = f"F{resize}"141 elif c == "F":142 # F: double (int args)143 resize = get_resize(default_width, 64)144 cur_mod = f"F{resize}"145 elif c == "H":146 # H: half (int args)147 resize = get_resize(default_width, 16)148 cur_mod = f"F{resize}"149 elif c == "0":150 # 0: half (int args), ignore 'Q' size modifier.151 resize = get_resize(default_width, 16)152 cur_mod = f"Fq{resize}"153 elif c == "1":154 # 1: half (int args), force 'Q' size modifier.155 resize = get_resize(default_width, 16)156 cur_mod = f"FQ{resize}"157 158 if len(cur_mod) == 0:159 raise Exception(f"WTF: {c} in {name}")160 161 if key_type != 0 and key_type == i:162 cur_mod += "!"163 164 if len(cur_mod) == 1:165 res += cur_mod166 else:167 res += "(" + cur_mod + ")"168 169 return res170 171 172def replace_insts(m):173 start, end = m.span("proto")174 start -= m.start()175 end -= m.start()176 new_proto = remap_protocol(m["proto"], m["kinds"], m["name"])177 return m.group()[:start] + new_proto + m.group()[end:]178 179 180INST = re.compile(r'Inst<"(?P<name>.*?)",\s*"(?P<proto>.*?)",\s*"(?P<kinds>.*?)"')181 182new_td = INST.sub(replace_insts, sys.stdin.read())183sys.stdout.write(new_td)184