[LLD][COFF] Emit tail merge pdata for delay load thunks on ARM64EC (#116810)
[llvm-project.git] / clang / utils / convert_arm_neon.py
blob836250c80452fd633b50047e600089aea9102a3b
1 #!/usr/bin/env python3
3 # This script was committed on 20/11/2019 and it would probably make sense to remove
4 # it after the next release branches.
6 # This script is pipe based and converts an arm_neon.td (or arm_fp16.td) file
7 # using the old single-char type modifiers to an equivalent new-style form where
8 # each modifier is orthogonal and they can be composed.
10 # It was used to directly generate the .td files on main, so if you have any
11 # local additions I would suggest implementing any modifiers here, and running
12 # it over your entire pre-merge .td files rather than trying to resolve any
13 # conflicts manually.
15 import re, sys
17 MOD_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",
53 def typespec_elt_size(typespec):
54 if "c" in typespec:
55 return 8
56 elif "s" in typespec or "h" in typespec:
57 return 16
58 elif "i" in typespec or "f" in typespec:
59 return 32
60 elif "l" in typespec or "d" in typespec:
61 return 64
62 elif "k" in typespec:
63 return 128
66 def get_resize(cur, desired):
67 res = ""
68 while cur < desired:
69 res += ">"
70 cur *= 2
71 while cur > desired:
72 res += "<"
73 cur /= 2
74 return res
77 def remap_protocol(proto, typespec, name):
78 key_type = 0
80 # Conversions like to see the integer type so they know signedness.
81 if (
82 "vcvt" in name
83 and "_f" in name
84 and name != "vcvt_f32_f64"
85 and name != "vcvt_f64_f32"
87 key_type = 1
88 default_width = typespec_elt_size(typespec)
89 inconsistent_width = False
90 for elt in typespec:
91 new_width = typespec_elt_size(elt)
92 if new_width and new_width != default_width:
93 inconsistent_width = True
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 += 1
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"
109 if c == "Y":
110 # y: scalar of half float
111 resize = get_resize(default_width, 16)
112 cur_mod = f"1F{resize}"
113 elif c == "y":
114 # y: scalar of float
115 resize = get_resize(default_width, 32)
116 cur_mod = f"1F{resize}"
117 elif c == "o":
118 # o: scalar of double
119 resize = get_resize(default_width, 64)
120 cur_mod = f"1F{resize}"
121 elif c == "I":
122 # I: scalar of 32-bit signed
123 resize = get_resize(default_width, 32)
124 cur_mod = f"1S{resize}"
125 elif c == "L":
126 # L: scalar of 64-bit signed
127 resize = get_resize(default_width, 64)
128 cur_mod = f"1S{resize}"
129 elif c == "U":
130 # I: scalar of 32-bit unsigned
131 resize = get_resize(default_width, 32)
132 cur_mod = f"1U{resize}"
133 elif c == "O":
134 # O: scalar of 64-bit unsigned
135 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}"
158 if len(cur_mod) == 0:
159 raise Exception(f"WTF: {c} in {name}")
161 if key_type != 0 and key_type == i:
162 cur_mod += "!"
164 if len(cur_mod) == 1:
165 res += cur_mod
166 else:
167 res += "(" + cur_mod + ")"
169 return res
172 def 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:]
180 INST = re.compile(r'Inst<"(?P<name>.*?)",\s*"(?P<proto>.*?)",\s*"(?P<kinds>.*?)"')
182 new_td = INST.sub(replace_insts, sys.stdin.read())
183 sys.stdout.write(new_td)