Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / utils / UpdateTestChecks / asm.py
blob7c3c60032e21301f13f218fe80f86e4e295990ea
1 from __future__ import print_function
2 import re
3 import sys
5 from . import common
7 if sys.version_info[0] > 2:
9 class string:
10 expandtabs = str.expandtabs
12 else:
13 import string
15 # RegEx: this is where the magic happens.
17 ##### Assembly parser
19 # The set of per-arch regular expressions define several groups.
20 # The required groups are "func" (function name) and "body" (body of the function).
21 # Although some backends require some additional groups like: "directives"
22 # and "func_name_separator"
24 ASM_FUNCTION_X86_RE = re.compile(
25 r'^_?(?P<func>[^:]+):[ \t]*#+[ \t]*(@"?(?P=func)"?| -- Begin function (?P=func))\n(?:\s*\.?Lfunc_begin[^:\n]*:\n)?'
26 r"(?:\.L(?P=func)\$local:\n)?" # drop .L<func>$local:
27 r"(?:\s*\.type\s+\.L(?P=func)\$local,@function\n)?" # drop .type .L<func>$local
28 r"(?:[ \t]*(?:\.cfi_startproc|\.cfi_personality|\.cfi_lsda|\.seh_proc|\.seh_handler)\b[^\n]*\n)*" # drop optional cfi
29 r"(?P<body>^##?[ \t]+[^:]+:.*?)\s*"
30 r"^\s*(?:[^:\n]+?:\s*\n\s*\.size|\.cfi_endproc|\.globl|\.comm|\.(?:sub)?section|#+ -- End function)",
31 flags=(re.M | re.S),
34 ASM_FUNCTION_ARM_RE = re.compile(
35 r"^(?P<func>[0-9a-zA-Z_$]+):\n" # f: (name of function)
36 r"(?:\.L(?P=func)\$local:\n)?" # drop .L<func>$local:
37 r"(?:\s*\.type\s+\.L(?P=func)\$local,@function\n)?" # drop .type .L<func>$local
38 r"\s+\.fnstart\n" # .fnstart
39 r"(?P<body>.*?)" # (body of the function)
40 r"^.Lfunc_end[0-9]+:", # .Lfunc_end0: or # -- End function
41 flags=(re.M | re.S),
44 ASM_FUNCTION_AARCH64_RE = re.compile(
45 r'^_?(?P<func>[^:]+):[ \t]*\/\/[ \t]*@"?(?P=func)"?( (Function|Tail Call))?\n'
46 r"(?:[ \t]+.cfi_startproc\n)?" # drop optional cfi noise
47 r"(?P<body>.*?)\n"
48 # This list is incomplete
49 r"^\s*(\.Lfunc_end[0-9]+|// -- End function)",
50 flags=(re.M | re.S),
53 ASM_FUNCTION_AMDGPU_RE = re.compile(
54 r'^_?(?P<func>[^:]+):[ \t]*;+[ \t]*@"?(?P=func)"?\n[^:]*?'
55 r"(?P<body>.*?)\n" # (body of the function)
56 # This list is incomplete
57 r"^\s*(\.Lfunc_end[0-9]+:\n|\.section)",
58 flags=(re.M | re.S),
61 ASM_FUNCTION_BPF_RE = re.compile(
62 r'^_?(?P<func>[^:]+):[ \t]*#+[ \t]*@"?(?P=func)"?\n'
63 r"(?:[ \t]+.cfi_startproc\n|.seh_proc[^\n]+\n)?" # drop optional cfi
64 r"(?P<body>.*?)\s*"
65 r".Lfunc_end[0-9]+:\n",
66 flags=(re.M | re.S),
69 ASM_FUNCTION_HEXAGON_RE = re.compile(
70 r'^_?(?P<func>[^:]+):[ \t]*//[ \t]*@"?(?P=func)"?\n[^:]*?'
71 r"(?P<body>.*?)\n" # (body of the function)
72 # This list is incomplete
73 r".Lfunc_end[0-9]+:\n",
74 flags=(re.M | re.S),
77 ASM_FUNCTION_M68K_RE = re.compile(
78 r'^_?(?P<func>[^:]+):[ \t]*;[ \t]*@"?(?P=func)"?\n'
79 r'(?:\.L(?P=func)\$local:\n)?' # drop .L<func>$local:
80 r'(?:[ \t]+\.type[ \t]+\.L(?P=func)\$local,@function\n)?' # drop .type .L<func>$local,@function
81 r'(?P<body>.*?)\s*' # (body of the function)
82 r'.Lfunc_end[0-9]+:\n',
83 flags=(re.M | re.S))
85 ASM_FUNCTION_MIPS_RE = re.compile(
86 r'^_?(?P<func>[^:]+):[ \t]*#+[ \t]*@"?(?P=func)"?\n[^:]*?' # f: (name of func)
87 r"(?:\s*\.?Ltmp[^:\n]*:\n)?[^:]*?" # optional .Ltmp<N> for EH
88 r"(?:^[ \t]+\.(frame|f?mask|set).*?\n)+" # Mips+LLVM standard asm prologue
89 r"(?P<body>.*?)\n" # (body of the function)
90 # Mips+LLVM standard asm epilogue
91 r"(?:(^[ \t]+\.set[^\n]*?\n)*^[ \t]+\.end.*?\n)"
92 r"(\$|\.L)func_end[0-9]+:\n", # $func_end0: (mips32 - O32) or
93 # .Lfunc_end0: (mips64 - NewABI)
94 flags=(re.M | re.S),
97 ASM_FUNCTION_MSP430_RE = re.compile(
98 r'^_?(?P<func>[^:]+):[ \t]*;+[ \t]*@"?(?P=func)"?\n[^:]*?'
99 r"(?P<body>.*?)\n"
100 r"(\$|\.L)func_end[0-9]+:\n", # $func_end0:
101 flags=(re.M | re.S),
104 ASM_FUNCTION_AVR_RE = re.compile(
105 r'^_?(?P<func>[^:]+):[ \t]*;+[ \t]*@"?(?P=func)"?\n[^:]*?'
106 r"(?P<body>.*?)\n"
107 r".Lfunc_end[0-9]+:\n",
108 flags=(re.M | re.S),
111 ASM_FUNCTION_PPC_RE = re.compile(
112 r"#[ \-\t]*Begin function (?P<func>[^.:]+)\n"
113 r".*?"
114 r'^[_.]?(?P=func):(?:[ \t]*#+[ \t]*@"?(?P=func)"?)?\n'
115 r"(?:^[^#]*\n)*"
116 r"(?P<body>.*?)\n"
117 # This list is incomplete
118 r"(?:^[ \t]*(?:\.(?:long|quad|v?byte)[ \t]+[^\n]+)\n)*"
119 r"(?:\.Lfunc_end|L\.\.(?P=func))[0-9]+:\n",
120 flags=(re.M | re.S),
123 ASM_FUNCTION_RISCV_RE = re.compile(
124 r'^_?(?P<func>[^:]+):[ \t]*#+[ \t]*@"?(?P=func)"?\n'
125 r"(?:\s*\.?L(?P=func)\$local:\n)?" # optional .L<func>$local: due to -fno-semantic-interposition
126 r"(?:\s*\.type\s+\.?L(?P=func)\$local,@function\n)?" # optional .type .L<func>$local
127 r"(?:\s*\.?Lfunc_begin[^:\n]*:\n)?[^:]*?"
128 r"(?P<body>^##?[ \t]+[^:]+:.*?)\s*"
129 r".Lfunc_end[0-9]+:\n",
130 flags=(re.M | re.S),
133 ASM_FUNCTION_LANAI_RE = re.compile(
134 r'^_?(?P<func>[^:]+):[ \t]*!+[ \t]*@"?(?P=func)"?\n'
135 r"(?:[ \t]+.cfi_startproc\n)?" # drop optional cfi noise
136 r"(?P<body>.*?)\s*"
137 r".Lfunc_end[0-9]+:\n",
138 flags=(re.M | re.S),
141 ASM_FUNCTION_SPARC_RE = re.compile(
142 r'^_?(?P<func>[^:]+):[ \t]*!+[ \t]*@"?(?P=func)"?\n'
143 r"(?P<body>.*?)\s*"
144 r".Lfunc_end[0-9]+:\n",
145 flags=(re.M | re.S),
148 ASM_FUNCTION_SYSTEMZ_RE = re.compile(
149 r'^_?(?P<func>[^:]+):[ \t]*#+[ \t]*@"?(?P=func)"?\n'
150 r"(?:[ \t]+.cfi_startproc\n)?"
151 r"(?P<body>.*?)\n"
152 r".Lfunc_end[0-9]+:\n",
153 flags=(re.M | re.S),
156 ASM_FUNCTION_AARCH64_DARWIN_RE = re.compile(
157 r'^_(?P<func>[^:]+):[ \t]*;[ \t]@"?(?P=func)"?\n'
158 r"([ \t]*.cfi_startproc\n[\s]*)?"
159 r"(?P<body>.*?)"
160 r"([ \t]*.cfi_endproc\n[\s]*)?"
161 r"^[ \t]*;[ \t]--[ \t]End[ \t]function",
162 flags=(re.M | re.S),
165 ASM_FUNCTION_ARM_DARWIN_RE = re.compile(
166 r"@[ \t]--[ \t]Begin[ \t]function[ \t](?P<func>[^ \t]+?)\n"
167 r"^[ \t]*\.globl[ \t]*_(?P=func)[ \t]*"
168 r"(?P<directives>.*?)"
169 r"^_(?P=func):\n[ \t]*"
170 r"(?P<body>.*?)"
171 r"^[ \t]*@[ \t]--[ \t]End[ \t]function",
172 flags=(re.M | re.S),
175 ASM_FUNCTION_ARM_MACHO_RE = re.compile(
176 r"^_(?P<func>[^:]+):[ \t]*\n"
177 r"([ \t]*.cfi_startproc\n[ \t]*)?"
178 r"(?P<body>.*?)\n"
179 r"[ \t]*\.cfi_endproc\n",
180 flags=(re.M | re.S),
183 ASM_FUNCTION_THUMBS_DARWIN_RE = re.compile(
184 r"^_(?P<func>[^:]+):\n" r"(?P<body>.*?)\n" r"[ \t]*\.data_region\n",
185 flags=(re.M | re.S),
188 ASM_FUNCTION_THUMB_DARWIN_RE = re.compile(
189 r"^_(?P<func>[^:]+):\n" r"(?P<body>.*?)\n" r"^[ \t]*@[ \t]--[ \t]End[ \t]function",
190 flags=(re.M | re.S),
193 ASM_FUNCTION_ARM_IOS_RE = re.compile(
194 r"^_(?P<func>[^:]+):\n" r"(?P<body>.*?)" r"^[ \t]*@[ \t]--[ \t]End[ \t]function",
195 flags=(re.M | re.S),
198 ASM_FUNCTION_WASM_RE = re.compile(
199 r'^_?(?P<func>[^:]+):[ \t]*#+[ \t]*@"?(?P=func)"?\n'
200 r"(?P<body>.*?)\n"
201 r"^\s*(\.Lfunc_end[0-9]+:\n|end_function)",
202 flags=(re.M | re.S),
205 # We parse the function name from OpName, and grab the variable name 'var'
206 # for this function. Then we match that when the variable is assigned with
207 # OpFunction and match its body.
208 ASM_FUNCTION_SPIRV_RE = re.compile(
209 r'OpName (?P<var>%[0-9]+) "(?P<func>[^"]+)(?P<func_name_separator>)".*(?P<body>(?P=var) = OpFunction.+?OpFunctionEnd)',
210 flags=(re.M | re.S),
213 ASM_FUNCTION_VE_RE = re.compile(
214 r"^_?(?P<func>[^:]+):[ \t]*#+[ \t]*@(?P=func)\n"
215 r"(?:\s*\.?L(?P=func)\$local:\n)?" # optional .L<func>$local: due to -fno-semantic-interposition
216 r"(?:\s*\.type\s+\.?L(?P=func)\$local,@function\n)?" # optional .type .L<func>$local
217 r"(?:\s*\.?Lfunc_begin[^:\n]*:\n)?[^:]*?"
218 r"(?P<body>^##?[ \t]+[^:]+:.*?)\s*"
219 r".Lfunc_end[0-9]+:\n",
220 flags=(re.M | re.S),
223 ASM_FUNCTION_CSKY_RE = re.compile(
224 r"^_?(?P<func>[^:]+):[ \t]*#+[ \t]*@(?P=func)\n(?:\s*\.?Lfunc_begin[^:\n]*:\n)?[^:]*?"
225 r"(?P<body>^##?[ \t]+[^:]+:.*?)\s*"
226 r".Lfunc_end[0-9]+:\n",
227 flags=(re.M | re.S),
230 ASM_FUNCTION_NVPTX_RE = re.compile(
231 # function attributes and retval
232 # .visible .func (.param .align 16 .b8 func_retval0[32])
233 # r'^(\.visible\s+)?\.func\s+(\([^\)]*\)\s*)?'
234 r"^(\.(func|visible|weak|entry|noreturn|extern)\s+)+(\([^\)]*\)\s*)?"
235 # function name
236 r"(?P<func>[^\(\n]+)"
237 # function name separator (opening brace)
238 r"(?P<func_name_separator>\()"
239 # function parameters
241 # .param .align 16 .b8 callee_St8x4_param_0[32]
242 # ) // -- Begin function callee_St8x4
243 r"[^\)]*\)(\s*//[^\n]*)?\n"
244 # function body
245 r"(?P<body>.*?)\n"
246 # function body end marker
247 r"\s*// -- End function",
248 flags=(re.M | re.S),
251 ASM_FUNCTION_LOONGARCH_RE = re.compile(
252 r'^_?(?P<func>[^:]+):[ \t]*#+[ \t]*@"?(?P=func)"?\n'
253 r"(?:\s*\.?Lfunc_begin[^:\n]*:\n)?[^:]*?"
254 r"(?P<body>^##?[ \t]+[^:]+:.*?)\s*"
255 r".Lfunc_end[0-9]+:\n",
256 flags=(re.M | re.S),
259 SCRUB_X86_SHUFFLES_RE = re.compile(
260 r"^(\s*\w+) [^#\n]+#+ ((?:[xyz]mm\d+|mem)( \{%k\d+\}( \{z\})?)? = .*)$", flags=re.M
263 SCRUB_X86_SHUFFLES_NO_MEM_RE = re.compile(
264 r"^(\s*\w+) [^#\n]+#+ ((?:[xyz]mm\d+|mem)( \{%k\d+\}( \{z\})?)? = (?!.*(?:mem)).*)$",
265 flags=re.M,
268 SCRUB_X86_SPILL_RELOAD_RE = re.compile(
269 r"-?\d+\(%([er])[sb]p\)(.*(?:Spill|Reload))$", flags=re.M
271 SCRUB_X86_SP_RE = re.compile(r"\d+\(%(esp|rsp)\)")
272 SCRUB_X86_RIP_RE = re.compile(r"[.\w]+\(%rip\)")
273 SCRUB_X86_LCP_RE = re.compile(r"\.?LCPI[0-9]+_[0-9]+")
274 SCRUB_X86_RET_RE = re.compile(r"ret[l|q]")
277 def scrub_asm_x86(asm, args):
278 # Scrub runs of whitespace out of the assembly, but leave the leading
279 # whitespace in place.
280 asm = common.SCRUB_WHITESPACE_RE.sub(r" ", asm)
281 # Expand the tabs used for indentation.
282 asm = string.expandtabs(asm, 2)
284 # Detect shuffle asm comments and hide the operands in favor of the comments.
285 if getattr(args, "no_x86_scrub_mem_shuffle", True):
286 asm = SCRUB_X86_SHUFFLES_NO_MEM_RE.sub(r"\1 {{.*#+}} \2", asm)
287 else:
288 asm = SCRUB_X86_SHUFFLES_RE.sub(r"\1 {{.*#+}} \2", asm)
290 # Detect stack spills and reloads and hide their exact offset and whether
291 # they used the stack pointer or frame pointer.
292 asm = SCRUB_X86_SPILL_RELOAD_RE.sub(r"{{[-0-9]+}}(%\1{{[sb]}}p)\2", asm)
293 if getattr(args, "x86_scrub_sp", True):
294 # Generically match the stack offset of a memory operand.
295 asm = SCRUB_X86_SP_RE.sub(r"{{[0-9]+}}(%\1)", asm)
296 if getattr(args, "x86_scrub_rip", False):
297 # Generically match a RIP-relative memory operand.
298 asm = SCRUB_X86_RIP_RE.sub(r"{{.*}}(%rip)", asm)
299 # Generically match a LCP symbol.
300 asm = SCRUB_X86_LCP_RE.sub(r"{{\.?LCPI[0-9]+_[0-9]+}}", asm)
301 if getattr(args, "extra_scrub", False):
302 # Avoid generating different checks for 32- and 64-bit because of 'retl' vs 'retq'.
303 asm = SCRUB_X86_RET_RE.sub(r"ret{{[l|q]}}", asm)
304 # Strip kill operands inserted into the asm.
305 asm = common.SCRUB_KILL_COMMENT_RE.sub("", asm)
306 # Strip trailing whitespace.
307 asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r"", asm)
308 return asm
311 def scrub_asm_amdgpu(asm, args):
312 # Scrub runs of whitespace out of the assembly, but leave the leading
313 # whitespace in place.
314 asm = common.SCRUB_WHITESPACE_RE.sub(r" ", asm)
315 # Expand the tabs used for indentation.
316 asm = string.expandtabs(asm, 2)
317 # Strip trailing whitespace.
318 asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r"", asm)
319 return asm
322 def scrub_asm_arm_eabi(asm, args):
323 # Scrub runs of whitespace out of the assembly, but leave the leading
324 # whitespace in place.
325 asm = common.SCRUB_WHITESPACE_RE.sub(r" ", asm)
326 # Expand the tabs used for indentation.
327 asm = string.expandtabs(asm, 2)
328 # Strip kill operands inserted into the asm.
329 asm = common.SCRUB_KILL_COMMENT_RE.sub("", asm)
330 # Strip trailing whitespace.
331 asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r"", asm)
332 return asm
335 def scrub_asm_bpf(asm, args):
336 # Scrub runs of whitespace out of the assembly, but leave the leading
337 # whitespace in place.
338 asm = common.SCRUB_WHITESPACE_RE.sub(r" ", asm)
339 # Expand the tabs used for indentation.
340 asm = string.expandtabs(asm, 2)
341 # Strip trailing whitespace.
342 asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r"", asm)
343 return asm
346 def scrub_asm_hexagon(asm, args):
347 # Scrub runs of whitespace out of the assembly, but leave the leading
348 # whitespace in place.
349 asm = common.SCRUB_WHITESPACE_RE.sub(r" ", asm)
350 # Expand the tabs used for indentation.
351 asm = string.expandtabs(asm, 2)
352 # Strip trailing whitespace.
353 asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r"", asm)
354 return asm
357 def scrub_asm_powerpc(asm, args):
358 # Scrub runs of whitespace out of the assembly, but leave the leading
359 # whitespace in place.
360 asm = common.SCRUB_WHITESPACE_RE.sub(r" ", asm)
361 # Expand the tabs used for indentation.
362 asm = string.expandtabs(asm, 2)
363 # Strip unimportant comments, but leave the token '#' in place.
364 asm = common.SCRUB_LOOP_COMMENT_RE.sub(r"#", asm)
365 # Strip trailing whitespace.
366 asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r"", asm)
367 # Strip the tailing token '#', except the line only has token '#'.
368 asm = common.SCRUB_TAILING_COMMENT_TOKEN_RE.sub(r"", asm)
369 return asm
372 def scrub_asm_m68k(asm, args):
373 # Scrub runs of whitespace out of the assembly, but leave the leading
374 # whitespace in place.
375 asm = common.SCRUB_WHITESPACE_RE.sub(r" ", asm)
376 # Expand the tabs used for indentation.
377 asm = string.expandtabs(asm, 2)
378 # Strip trailing whitespace.
379 asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r"", asm)
380 return asm
383 def scrub_asm_mips(asm, args):
384 # Scrub runs of whitespace out of the assembly, but leave the leading
385 # whitespace in place.
386 asm = common.SCRUB_WHITESPACE_RE.sub(r" ", asm)
387 # Expand the tabs used for indentation.
388 asm = string.expandtabs(asm, 2)
389 # Strip trailing whitespace.
390 asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r"", asm)
391 return asm
394 def scrub_asm_msp430(asm, args):
395 # Scrub runs of whitespace out of the assembly, but leave the leading
396 # whitespace in place.
397 asm = common.SCRUB_WHITESPACE_RE.sub(r" ", asm)
398 # Expand the tabs used for indentation.
399 asm = string.expandtabs(asm, 2)
400 # Strip trailing whitespace.
401 asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r"", asm)
402 return asm
405 def scrub_asm_avr(asm, args):
406 # Scrub runs of whitespace out of the assembly, but leave the leading
407 # whitespace in place.
408 asm = common.SCRUB_WHITESPACE_RE.sub(r" ", asm)
409 # Expand the tabs used for indentation.
410 asm = string.expandtabs(asm, 2)
411 # Strip trailing whitespace.
412 asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r"", asm)
413 return asm
416 def scrub_asm_riscv(asm, args):
417 # Scrub runs of whitespace out of the assembly, but leave the leading
418 # whitespace in place.
419 asm = common.SCRUB_WHITESPACE_RE.sub(r" ", asm)
420 # Expand the tabs used for indentation.
421 asm = string.expandtabs(asm, 2)
422 # Strip trailing whitespace.
423 asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r"", asm)
424 return asm
427 def scrub_asm_lanai(asm, args):
428 # Scrub runs of whitespace out of the assembly, but leave the leading
429 # whitespace in place.
430 asm = common.SCRUB_WHITESPACE_RE.sub(r" ", asm)
431 # Expand the tabs used for indentation.
432 asm = string.expandtabs(asm, 2)
433 # Strip trailing whitespace.
434 asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r"", asm)
435 return asm
438 def scrub_asm_sparc(asm, args):
439 # Scrub runs of whitespace out of the assembly, but leave the leading
440 # whitespace in place.
441 asm = common.SCRUB_WHITESPACE_RE.sub(r" ", asm)
442 # Expand the tabs used for indentation.
443 asm = string.expandtabs(asm, 2)
444 # Strip trailing whitespace.
445 asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r"", asm)
446 return asm
449 def scrub_asm_spirv(asm, args):
450 # Scrub runs of whitespace out of the assembly, but leave the leading
451 # whitespace in place.
452 asm = common.SCRUB_WHITESPACE_RE.sub(r" ", asm)
453 # Expand the tabs used for indentation.
454 asm = string.expandtabs(asm, 2)
455 # Strip trailing whitespace.
456 asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r"", asm)
457 return asm
460 def scrub_asm_systemz(asm, args):
461 # Scrub runs of whitespace out of the assembly, but leave the leading
462 # whitespace in place.
463 asm = common.SCRUB_WHITESPACE_RE.sub(r" ", asm)
464 # Expand the tabs used for indentation.
465 asm = string.expandtabs(asm, 2)
466 # Strip trailing whitespace.
467 asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r"", asm)
468 return asm
471 def scrub_asm_wasm(asm, args):
472 # Scrub runs of whitespace out of the assembly, but leave the leading
473 # whitespace in place.
474 asm = common.SCRUB_WHITESPACE_RE.sub(r" ", asm)
475 # Expand the tabs used for indentation.
476 asm = string.expandtabs(asm, 2)
477 # Strip trailing whitespace.
478 asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r"", asm)
479 return asm
482 def scrub_asm_ve(asm, args):
483 # Scrub runs of whitespace out of the assembly, but leave the leading
484 # whitespace in place.
485 asm = common.SCRUB_WHITESPACE_RE.sub(r" ", asm)
486 # Expand the tabs used for indentation.
487 asm = string.expandtabs(asm, 2)
488 # Strip trailing whitespace.
489 asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r"", asm)
490 return asm
493 def scrub_asm_csky(asm, args):
494 # Scrub runs of whitespace out of the assembly, but leave the leading
495 # whitespace in place.
496 asm = common.SCRUB_WHITESPACE_RE.sub(r" ", asm)
497 # Expand the tabs used for indentation.
498 asm = string.expandtabs(asm, 2)
499 # Strip kill operands inserted into the asm.
500 asm = common.SCRUB_KILL_COMMENT_RE.sub("", asm)
501 # Strip trailing whitespace.
502 asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r"", asm)
503 return asm
506 def scrub_asm_nvptx(asm, args):
507 # Scrub runs of whitespace out of the assembly, but leave the leading
508 # whitespace in place.
509 asm = common.SCRUB_WHITESPACE_RE.sub(r" ", asm)
510 # Expand the tabs used for indentation.
511 asm = string.expandtabs(asm, 2)
512 # Strip trailing whitespace.
513 asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r"", asm)
514 return asm
517 def scrub_asm_loongarch(asm, args):
518 # Scrub runs of whitespace out of the assembly, but leave the leading
519 # whitespace in place.
520 asm = common.SCRUB_WHITESPACE_RE.sub(r" ", asm)
521 # Expand the tabs used for indentation.
522 asm = string.expandtabs(asm, 2)
523 # Strip trailing whitespace.
524 asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r"", asm)
525 return asm
528 # Returns a tuple of a scrub function and a function regex. Scrub function is
529 # used to alter function body in some way, for example, remove trailing spaces.
530 # Function regex is used to match function name, body, etc. in raw llc output.
531 def get_run_handler(triple):
532 target_handlers = {
533 "i686": (scrub_asm_x86, ASM_FUNCTION_X86_RE),
534 "x86": (scrub_asm_x86, ASM_FUNCTION_X86_RE),
535 "i386": (scrub_asm_x86, ASM_FUNCTION_X86_RE),
536 "arm64_32-apple-ios": (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_DARWIN_RE),
537 "arm64_32-apple-watchos2.0.0": (
538 scrub_asm_arm_eabi,
539 ASM_FUNCTION_AARCH64_DARWIN_RE,
541 "aarch64": (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_RE),
542 "aarch64-apple-darwin": (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_DARWIN_RE),
543 "aarch64-apple-ios": (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_DARWIN_RE),
544 "bpf": (scrub_asm_bpf, ASM_FUNCTION_BPF_RE),
545 "bpfel": (scrub_asm_bpf, ASM_FUNCTION_BPF_RE),
546 "bpfeb": (scrub_asm_bpf, ASM_FUNCTION_BPF_RE),
547 "hexagon": (scrub_asm_hexagon, ASM_FUNCTION_HEXAGON_RE),
548 "r600": (scrub_asm_amdgpu, ASM_FUNCTION_AMDGPU_RE),
549 "amdgcn": (scrub_asm_amdgpu, ASM_FUNCTION_AMDGPU_RE),
550 "arm": (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_RE),
551 "arm64": (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_RE),
552 "arm64e": (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_DARWIN_RE),
553 "arm64ec": (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_RE),
554 "arm64-apple-ios": (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_DARWIN_RE),
555 "armv7-apple-ios": (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_IOS_RE),
556 "armv7-apple-darwin": (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_DARWIN_RE),
557 "thumb": (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_RE),
558 "thumb-macho": (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_MACHO_RE),
559 "thumbv5-macho": (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_MACHO_RE),
560 "thumbv7s-apple-darwin": (scrub_asm_arm_eabi, ASM_FUNCTION_THUMBS_DARWIN_RE),
561 "thumbv7-apple-darwin": (scrub_asm_arm_eabi, ASM_FUNCTION_THUMB_DARWIN_RE),
562 "thumbv7-apple-ios": (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_IOS_RE),
563 "m68k": (scrub_asm_m68k, ASM_FUNCTION_M68K_RE),
564 "mips": (scrub_asm_mips, ASM_FUNCTION_MIPS_RE),
565 "msp430": (scrub_asm_msp430, ASM_FUNCTION_MSP430_RE),
566 "avr": (scrub_asm_avr, ASM_FUNCTION_AVR_RE),
567 "ppc32": (scrub_asm_powerpc, ASM_FUNCTION_PPC_RE),
568 "ppc64": (scrub_asm_powerpc, ASM_FUNCTION_PPC_RE),
569 "powerpc": (scrub_asm_powerpc, ASM_FUNCTION_PPC_RE),
570 "riscv32": (scrub_asm_riscv, ASM_FUNCTION_RISCV_RE),
571 "riscv64": (scrub_asm_riscv, ASM_FUNCTION_RISCV_RE),
572 "lanai": (scrub_asm_lanai, ASM_FUNCTION_LANAI_RE),
573 "sparc": (scrub_asm_sparc, ASM_FUNCTION_SPARC_RE),
574 "spirv32": (scrub_asm_spirv, ASM_FUNCTION_SPIRV_RE),
575 "spirv64": (scrub_asm_spirv, ASM_FUNCTION_SPIRV_RE),
576 "s390x": (scrub_asm_systemz, ASM_FUNCTION_SYSTEMZ_RE),
577 "wasm32": (scrub_asm_wasm, ASM_FUNCTION_WASM_RE),
578 "wasm64": (scrub_asm_wasm, ASM_FUNCTION_WASM_RE),
579 "ve": (scrub_asm_ve, ASM_FUNCTION_VE_RE),
580 "csky": (scrub_asm_csky, ASM_FUNCTION_CSKY_RE),
581 "nvptx": (scrub_asm_nvptx, ASM_FUNCTION_NVPTX_RE),
582 "loongarch32": (scrub_asm_loongarch, ASM_FUNCTION_LOONGARCH_RE),
583 "loongarch64": (scrub_asm_loongarch, ASM_FUNCTION_LOONGARCH_RE),
585 handler = None
586 best_prefix = ""
587 for prefix, s in target_handlers.items():
588 if triple.startswith(prefix) and len(prefix) > len(best_prefix):
589 handler = s
590 best_prefix = prefix
592 if handler is None:
593 raise KeyError("Triple %r is not supported" % (triple))
595 return handler
598 ##### Generator of assembly CHECK lines
601 def add_checks(
602 output_lines,
603 comment_marker,
604 prefix_list,
605 func_dict,
606 func_name,
607 global_vars_seen_dict,
608 is_filtered,
610 # Label format is based on ASM string.
611 check_label_format = "{} %s-LABEL: %s%s%s%s".format(comment_marker)
612 return common.add_checks(
613 output_lines,
614 comment_marker,
615 prefix_list,
616 func_dict,
617 func_name,
618 check_label_format,
619 True,
620 False,
622 global_vars_seen_dict,
623 is_filtered=is_filtered,