xref: /llvm-project/llvm/utils/UpdateTestChecks/asm.py (revision 4658366d95d5e398baad956225cc4ba339d5b037)
1from __future__ import print_function
2import re
3import sys
4
5from . import common
6
7if sys.version_info[0] > 2:
8  class string:
9    expandtabs = str.expandtabs
10else:
11  import string
12
13# RegEx: this is where the magic happens.
14
15##### Assembly parser
16
17ASM_FUNCTION_X86_RE = re.compile(
18    r'^_?(?P<func>[^:]+):[ \t]*#+[ \t]*(@"?(?P=func)"?| -- Begin function (?P=func))\n(?:\s*\.?Lfunc_begin[^:\n]*:\n)?'
19    r'(?:\.L(?P=func)\$local:\n)?'      # drop .L<func>$local:
20    r'(?:\s*\.type\s+\.L(?P=func)\$local,@function\n)?'  # drop .type .L<func>$local
21    r'(?:[ \t]+.cfi_startproc\n|.seh_proc[^\n]+\n)?'  # drop optional cfi
22    r'(?P<body>^##?[ \t]+[^:]+:.*?)\s*'
23    r'^\s*(?:[^:\n]+?:\s*\n\s*\.size|\.cfi_endproc|\.globl|\.comm|\.(?:sub)?section|#+ -- End function)',
24    flags=(re.M | re.S))
25
26ASM_FUNCTION_ARM_RE = re.compile(
27    r'^(?P<func>[0-9a-zA-Z_$]+):\n' # f: (name of function)
28    r'(?:\.L(?P=func)\$local:\n)?'  # drop .L<func>$local:
29    r'(?:\s*\.type\s+\.L(?P=func)\$local,@function\n)?'  # drop .type .L<func>$local
30    r'\s+\.fnstart\n' # .fnstart
31    r'(?P<body>.*?)' # (body of the function)
32    r'^.Lfunc_end[0-9]+:', # .Lfunc_end0: or # -- End function
33    flags=(re.M | re.S))
34
35ASM_FUNCTION_AARCH64_RE = re.compile(
36     r'^_?(?P<func>[^:]+):[ \t]*\/\/[ \t]*@"?(?P=func)"?( (Function|Tail Call))?\n'
37     r'(?:[ \t]+.cfi_startproc\n)?'  # drop optional cfi noise
38     r'(?P<body>.*?)\n'
39     # This list is incomplete
40     r'^\s*(\.Lfunc_end[0-9]+|// -- End function)',
41     flags=(re.M | re.S))
42
43ASM_FUNCTION_AMDGPU_RE = re.compile(
44    r'^_?(?P<func>[^:]+):[ \t]*;+[ \t]*@"?(?P=func)"?\n[^:]*?'
45    r'(?P<body>.*?)\n' # (body of the function)
46    # This list is incomplete
47    r'^\s*(\.Lfunc_end[0-9]+:\n|\.section)',
48    flags=(re.M | re.S))
49
50ASM_FUNCTION_HEXAGON_RE = re.compile(
51    r'^_?(?P<func>[^:]+):[ \t]*//[ \t]*@"?(?P=func)"?\n[^:]*?'
52    r'(?P<body>.*?)\n' # (body of the function)
53    # This list is incomplete
54    r'.Lfunc_end[0-9]+:\n',
55    flags=(re.M | re.S))
56
57ASM_FUNCTION_M68K_RE = re.compile(
58    r'^_?(?P<func>[^:]+):[ \t]*;[ \t]*@"?(?P=func)"?\n'
59    r'(?P<body>.*?)\s*' # (body of the function)
60    r'.Lfunc_end[0-9]+:\n',
61    flags=(re.M | re.S))
62
63ASM_FUNCTION_MIPS_RE = re.compile(
64    r'^_?(?P<func>[^:]+):[ \t]*#+[ \t]*@"?(?P=func)"?\n[^:]*?' # f: (name of func)
65    r'(?:\s*\.?Ltmp[^:\n]*:\n)?[^:]*?'        # optional .Ltmp<N> for EH
66    r'(?:^[ \t]+\.(frame|f?mask|set).*?\n)+'  # Mips+LLVM standard asm prologue
67    r'(?P<body>.*?)\n'                        # (body of the function)
68    # Mips+LLVM standard asm epilogue
69    r'(?:(^[ \t]+\.set[^\n]*?\n)*^[ \t]+\.end.*?\n)'
70    r'(\$|\.L)func_end[0-9]+:\n',             # $func_end0: (mips32 - O32) or
71                                              # .Lfunc_end0: (mips64 - NewABI)
72    flags=(re.M | re.S))
73
74ASM_FUNCTION_MSP430_RE = re.compile(
75    r'^_?(?P<func>[^:]+):[ \t]*;+[ \t]*@"?(?P=func)"?\n[^:]*?'
76    r'(?P<body>.*?)\n'
77    r'(\$|\.L)func_end[0-9]+:\n',             # $func_end0:
78    flags=(re.M | re.S))
79
80ASM_FUNCTION_AVR_RE = re.compile(
81    r'^_?(?P<func>[^:]+):[ \t]*;+[ \t]*@"?(?P=func)"?\n[^:]*?'
82    r'(?P<body>.*?)\n'
83    r'.Lfunc_end[0-9]+:\n',
84    flags=(re.M | re.S))
85
86ASM_FUNCTION_PPC_RE = re.compile(
87    r'#[ \-\t]*Begin function (?P<func>[^.:]+)\n'
88    r'.*?'
89    r'^[_.]?(?P=func):(?:[ \t]*#+[ \t]*@"?(?P=func)"?)?\n'
90    r'(?:^[^#]*\n)*'
91    r'(?P<body>.*?)\n'
92    # This list is incomplete
93    r'(?:^[ \t]*(?:\.(?:long|quad|v?byte)[ \t]+[^\n]+)\n)*'
94    r'(?:\.Lfunc_end|L\.\.(?P=func))[0-9]+:\n',
95    flags=(re.M | re.S))
96
97ASM_FUNCTION_RISCV_RE = re.compile(
98    r'^_?(?P<func>[^:]+):[ \t]*#+[ \t]*@"?(?P=func)"?\n'
99    r'(?:\s*\.?L(?P=func)\$local:\n)?'  # optional .L<func>$local: due to -fno-semantic-interposition
100    r'(?:\s*\.type\s+\.?L(?P=func)\$local,@function\n)?'  # optional .type .L<func>$local
101    r'(?:\s*\.?Lfunc_begin[^:\n]*:\n)?[^:]*?'
102    r'(?P<body>^##?[ \t]+[^:]+:.*?)\s*'
103    r'.Lfunc_end[0-9]+:\n',
104    flags=(re.M | re.S))
105
106ASM_FUNCTION_LANAI_RE = re.compile(
107    r'^_?(?P<func>[^:]+):[ \t]*!+[ \t]*@"?(?P=func)"?\n'
108    r'(?:[ \t]+.cfi_startproc\n)?'  # drop optional cfi noise
109    r'(?P<body>.*?)\s*'
110    r'.Lfunc_end[0-9]+:\n',
111    flags=(re.M | re.S))
112
113ASM_FUNCTION_SPARC_RE = re.compile(
114    r'^_?(?P<func>[^:]+):[ \t]*!+[ \t]*@"?(?P=func)"?\n'
115    r'(?P<body>.*?)\s*'
116    r'.Lfunc_end[0-9]+:\n',
117    flags=(re.M | re.S))
118
119ASM_FUNCTION_SYSTEMZ_RE = re.compile(
120    r'^_?(?P<func>[^:]+):[ \t]*#+[ \t]*@"?(?P=func)"?\n'
121    r'[ \t]+.cfi_startproc\n'
122    r'(?P<body>.*?)\n'
123    r'.Lfunc_end[0-9]+:\n',
124    flags=(re.M | re.S))
125
126ASM_FUNCTION_AARCH64_DARWIN_RE = re.compile(
127    r'^_(?P<func>[^:]+):[ \t]*;[ \t]@"?(?P=func)"?\n'
128    r'([ \t]*.cfi_startproc\n[\s]*)?'
129    r'(?P<body>.*?)'
130    r'([ \t]*.cfi_endproc\n[\s]*)?'
131    r'^[ \t]*;[ \t]--[ \t]End[ \t]function',
132    flags=(re.M | re.S))
133
134ASM_FUNCTION_ARM_DARWIN_RE = re.compile(
135    r'@[ \t]--[ \t]Begin[ \t]function[ \t](?P<func>[^ \t]+?)\n'
136    r'^[ \t]*\.globl[ \t]*_(?P=func)[ \t]*'
137    r'(?P<directives>.*?)'
138    r'^_(?P=func):\n[ \t]*'
139    r'(?P<body>.*?)'
140    r'^[ \t]*@[ \t]--[ \t]End[ \t]function',
141    flags=(re.M | re.S ))
142
143ASM_FUNCTION_ARM_MACHO_RE = re.compile(
144    r'^_(?P<func>[^:]+):[ \t]*\n'
145    r'([ \t]*.cfi_startproc\n[ \t]*)?'
146    r'(?P<body>.*?)\n'
147    r'[ \t]*\.cfi_endproc\n',
148    flags=(re.M | re.S))
149
150ASM_FUNCTION_THUMBS_DARWIN_RE = re.compile(
151    r'^_(?P<func>[^:]+):\n'
152    r'(?P<body>.*?)\n'
153    r'[ \t]*\.data_region\n',
154    flags=(re.M | re.S))
155
156ASM_FUNCTION_THUMB_DARWIN_RE = re.compile(
157    r'^_(?P<func>[^:]+):\n'
158    r'(?P<body>.*?)\n'
159    r'^[ \t]*@[ \t]--[ \t]End[ \t]function',
160    flags=(re.M | re.S))
161
162ASM_FUNCTION_ARM_IOS_RE = re.compile(
163    r'^_(?P<func>[^:]+):\n'
164    r'(?P<body>.*?)'
165    r'^[ \t]*@[ \t]--[ \t]End[ \t]function',
166    flags=(re.M | re.S))
167
168ASM_FUNCTION_WASM32_RE = re.compile(
169    r'^_?(?P<func>[^:]+):[ \t]*#+[ \t]*@"?(?P=func)"?\n'
170    r'(?P<body>.*?)\n'
171    r'^\s*(\.Lfunc_end[0-9]+:\n|end_function)',
172    flags=(re.M | re.S))
173
174ASM_FUNCTION_VE_RE = re.compile(
175    r'^_?(?P<func>[^:]+):[ \t]*#+[ \t]*@(?P=func)\n'
176    r'(?:\s*\.?L(?P=func)\$local:\n)?'  # optional .L<func>$local: due to -fno-semantic-interposition
177    r'(?:\s*\.type\s+\.?L(?P=func)\$local,@function\n)?'  # optional .type .L<func>$local
178    r'(?:\s*\.?Lfunc_begin[^:\n]*:\n)?[^:]*?'
179    r'(?P<body>^##?[ \t]+[^:]+:.*?)\s*'
180    r'.Lfunc_end[0-9]+:\n',
181    flags=(re.M | re.S))
182
183ASM_FUNCTION_CSKY_RE = re.compile(
184    r'^_?(?P<func>[^:]+):[ \t]*#+[ \t]*@(?P=func)\n(?:\s*\.?Lfunc_begin[^:\n]*:\n)?[^:]*?'
185    r'(?P<body>^##?[ \t]+[^:]+:.*?)\s*'
186    r'.Lfunc_end[0-9]+:\n',
187    flags=(re.M | re.S))
188
189ASM_FUNCTION_NVPTX_RE = re.compile(
190    # function attributes and retval
191    # .visible .func (.param .align 16 .b8 func_retval0[32])
192    #r'^(\.visible\s+)?\.func\s+(\([^\)]*\)\s*)?'
193    r'^(\.(func|visible|weak|entry|noreturn|extern)\s+)+(\([^\)]*\)\s*)?'
194
195    # function name
196    r'(?P<func>[^\(\n]+)'
197
198    # function name separator (opening brace)
199    r'(?P<func_name_separator>\()'
200
201    # function parameters
202    # (
203    #   .param .align 16 .b8 callee_St8x4_param_0[32]
204    # ) // -- Begin function callee_St8x4
205    r'[^\)]*\)(\s*//[^\n]*)?\n'
206
207    # function body
208    r'(?P<body>.*?)\n'
209
210    # function body end marker
211    r'\s*// -- End function',
212    flags=(re.M | re.S))
213
214ASM_FUNCTION_LOONGARCH_RE = re.compile(
215    r'^_?(?P<func>[^:]+):[ \t]*#+[ \t]*@"?(?P=func)"?\n'
216    r'(?:\s*\.?Lfunc_begin[^:\n]*:\n)?[^:]*?'
217    r'(?P<body>^##?[ \t]+[^:]+:.*?)\s*'
218    r'.Lfunc_end[0-9]+:\n',
219    flags=(re.M | re.S))
220
221SCRUB_X86_SHUFFLES_RE = (
222    re.compile(
223        r'^(\s*\w+) [^#\n]+#+ ((?:[xyz]mm\d+|mem)( \{%k\d+\}( \{z\})?)? = .*)$',
224        flags=re.M))
225
226SCRUB_X86_SHUFFLES_NO_MEM_RE = (
227    re.compile(
228        r'^(\s*\w+) [^#\n]+#+ ((?:[xyz]mm\d+|mem)( \{%k\d+\}( \{z\})?)? = (?!.*(?:mem)).*)$',
229        flags=re.M))
230
231SCRUB_X86_SPILL_RELOAD_RE = (
232    re.compile(
233        r'-?\d+\(%([er])[sb]p\)(.*(?:Spill|Reload))$',
234        flags=re.M))
235SCRUB_X86_SP_RE = re.compile(r'\d+\(%(esp|rsp)\)')
236SCRUB_X86_RIP_RE = re.compile(r'[.\w]+\(%rip\)')
237SCRUB_X86_LCP_RE = re.compile(r'\.?LCPI[0-9]+_[0-9]+')
238SCRUB_X86_RET_RE = re.compile(r'ret[l|q]')
239
240def scrub_asm_x86(asm, args):
241  # Scrub runs of whitespace out of the assembly, but leave the leading
242  # whitespace in place.
243  asm = common.SCRUB_WHITESPACE_RE.sub(r' ', asm)
244  # Expand the tabs used for indentation.
245  asm = string.expandtabs(asm, 2)
246
247  # Detect shuffle asm comments and hide the operands in favor of the comments.
248  if getattr(args, 'no_x86_scrub_mem_shuffle', True):
249    asm = SCRUB_X86_SHUFFLES_NO_MEM_RE.sub(r'\1 {{.*#+}} \2', asm)
250  else:
251    asm = SCRUB_X86_SHUFFLES_RE.sub(r'\1 {{.*#+}} \2', asm)
252
253  # Detect stack spills and reloads and hide their exact offset and whether
254  # they used the stack pointer or frame pointer.
255  asm = SCRUB_X86_SPILL_RELOAD_RE.sub(r'{{[-0-9]+}}(%\1{{[sb]}}p)\2', asm)
256  if getattr(args, 'x86_scrub_sp', True):
257    # Generically match the stack offset of a memory operand.
258    asm = SCRUB_X86_SP_RE.sub(r'{{[0-9]+}}(%\1)', asm)
259  if getattr(args, 'x86_scrub_rip', False):
260    # Generically match a RIP-relative memory operand.
261    asm = SCRUB_X86_RIP_RE.sub(r'{{.*}}(%rip)', asm)
262  # Generically match a LCP symbol.
263  asm = SCRUB_X86_LCP_RE.sub(r'{{\.?LCPI[0-9]+_[0-9]+}}', asm)
264  if getattr(args, 'extra_scrub', False):
265    # Avoid generating different checks for 32- and 64-bit because of 'retl' vs 'retq'.
266    asm = SCRUB_X86_RET_RE.sub(r'ret{{[l|q]}}', asm)
267  # Strip kill operands inserted into the asm.
268  asm = common.SCRUB_KILL_COMMENT_RE.sub('', asm)
269  # Strip trailing whitespace.
270  asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm)
271  return asm
272
273def scrub_asm_amdgpu(asm, args):
274  # Scrub runs of whitespace out of the assembly, but leave the leading
275  # whitespace in place.
276  asm = common.SCRUB_WHITESPACE_RE.sub(r' ', asm)
277  # Expand the tabs used for indentation.
278  asm = string.expandtabs(asm, 2)
279  # Strip trailing whitespace.
280  asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm)
281  return asm
282
283def scrub_asm_arm_eabi(asm, args):
284  # Scrub runs of whitespace out of the assembly, but leave the leading
285  # whitespace in place.
286  asm = common.SCRUB_WHITESPACE_RE.sub(r' ', asm)
287  # Expand the tabs used for indentation.
288  asm = string.expandtabs(asm, 2)
289  # Strip kill operands inserted into the asm.
290  asm = common.SCRUB_KILL_COMMENT_RE.sub('', asm)
291  # Strip trailing whitespace.
292  asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm)
293  return asm
294
295def scrub_asm_hexagon(asm, args):
296  # Scrub runs of whitespace out of the assembly, but leave the leading
297  # whitespace in place.
298  asm = common.SCRUB_WHITESPACE_RE.sub(r' ', asm)
299  # Expand the tabs used for indentation.
300  asm = string.expandtabs(asm, 2)
301  # Strip trailing whitespace.
302  asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm)
303  return asm
304
305def scrub_asm_powerpc(asm, args):
306  # Scrub runs of whitespace out of the assembly, but leave the leading
307  # whitespace in place.
308  asm = common.SCRUB_WHITESPACE_RE.sub(r' ', asm)
309  # Expand the tabs used for indentation.
310  asm = string.expandtabs(asm, 2)
311  # Strip unimportant comments, but leave the token '#' in place.
312  asm = common.SCRUB_LOOP_COMMENT_RE.sub(r'#', asm)
313  # Strip trailing whitespace.
314  asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm)
315  # Strip the tailing token '#', except the line only has token '#'.
316  asm = common.SCRUB_TAILING_COMMENT_TOKEN_RE.sub(r'', asm)
317  return asm
318
319def scrub_asm_m68k(asm, args):
320  # Scrub runs of whitespace out of the assembly, but leave the leading
321  # whitespace in place.
322  asm = common.SCRUB_WHITESPACE_RE.sub(r' ', asm)
323  # Expand the tabs used for indentation.
324  asm = string.expandtabs(asm, 2)
325  # Strip trailing whitespace.
326  asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm)
327  return asm
328
329def scrub_asm_mips(asm, args):
330  # Scrub runs of whitespace out of the assembly, but leave the leading
331  # whitespace in place.
332  asm = common.SCRUB_WHITESPACE_RE.sub(r' ', asm)
333  # Expand the tabs used for indentation.
334  asm = string.expandtabs(asm, 2)
335  # Strip trailing whitespace.
336  asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm)
337  return asm
338
339def scrub_asm_msp430(asm, args):
340  # Scrub runs of whitespace out of the assembly, but leave the leading
341  # whitespace in place.
342  asm = common.SCRUB_WHITESPACE_RE.sub(r' ', asm)
343  # Expand the tabs used for indentation.
344  asm = string.expandtabs(asm, 2)
345  # Strip trailing whitespace.
346  asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm)
347  return asm
348
349def scrub_asm_avr(asm, args):
350  # Scrub runs of whitespace out of the assembly, but leave the leading
351  # whitespace in place.
352  asm = common.SCRUB_WHITESPACE_RE.sub(r' ', asm)
353  # Expand the tabs used for indentation.
354  asm = string.expandtabs(asm, 2)
355  # Strip trailing whitespace.
356  asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm)
357  return asm
358
359def scrub_asm_riscv(asm, args):
360  # Scrub runs of whitespace out of the assembly, but leave the leading
361  # whitespace in place.
362  asm = common.SCRUB_WHITESPACE_RE.sub(r' ', asm)
363  # Expand the tabs used for indentation.
364  asm = string.expandtabs(asm, 2)
365  # Strip trailing whitespace.
366  asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm)
367  return asm
368
369def scrub_asm_lanai(asm, args):
370  # Scrub runs of whitespace out of the assembly, but leave the leading
371  # whitespace in place.
372  asm = common.SCRUB_WHITESPACE_RE.sub(r' ', asm)
373  # Expand the tabs used for indentation.
374  asm = string.expandtabs(asm, 2)
375  # Strip trailing whitespace.
376  asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm)
377  return asm
378
379def scrub_asm_sparc(asm, args):
380  # Scrub runs of whitespace out of the assembly, but leave the leading
381  # whitespace in place.
382  asm = common.SCRUB_WHITESPACE_RE.sub(r' ', asm)
383  # Expand the tabs used for indentation.
384  asm = string.expandtabs(asm, 2)
385  # Strip trailing whitespace.
386  asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm)
387  return asm
388
389def scrub_asm_systemz(asm, args):
390  # Scrub runs of whitespace out of the assembly, but leave the leading
391  # whitespace in place.
392  asm = common.SCRUB_WHITESPACE_RE.sub(r' ', asm)
393  # Expand the tabs used for indentation.
394  asm = string.expandtabs(asm, 2)
395  # Strip trailing whitespace.
396  asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm)
397  return asm
398
399def scrub_asm_wasm32(asm, args):
400  # Scrub runs of whitespace out of the assembly, but leave the leading
401  # whitespace in place.
402  asm = common.SCRUB_WHITESPACE_RE.sub(r' ', asm)
403  # Expand the tabs used for indentation.
404  asm = string.expandtabs(asm, 2)
405  # Strip trailing whitespace.
406  asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm)
407  return asm
408
409def scrub_asm_ve(asm, args):
410  # Scrub runs of whitespace out of the assembly, but leave the leading
411  # whitespace in place.
412  asm = common.SCRUB_WHITESPACE_RE.sub(r' ', asm)
413  # Expand the tabs used for indentation.
414  asm = string.expandtabs(asm, 2)
415  # Strip trailing whitespace.
416  asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm)
417  return asm
418
419def scrub_asm_csky(asm, args):
420  # Scrub runs of whitespace out of the assembly, but leave the leading
421  # whitespace in place.
422  asm = common.SCRUB_WHITESPACE_RE.sub(r' ', asm)
423  # Expand the tabs used for indentation.
424  asm = string.expandtabs(asm, 2)
425  # Strip kill operands inserted into the asm.
426  asm = common.SCRUB_KILL_COMMENT_RE.sub('', asm)
427  # Strip trailing whitespace.
428  asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm)
429  return asm
430
431def scrub_asm_nvptx(asm, args):
432  # Scrub runs of whitespace out of the assembly, but leave the leading
433  # whitespace in place.
434  asm = common.SCRUB_WHITESPACE_RE.sub(r' ', asm)
435  # Expand the tabs used for indentation.
436  asm = string.expandtabs(asm, 2)
437  # Strip trailing whitespace.
438  asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm)
439  return asm
440
441def scrub_asm_loongarch(asm, args):
442  # Scrub runs of whitespace out of the assembly, but leave the leading
443  # whitespace in place.
444  asm = common.SCRUB_WHITESPACE_RE.sub(r' ', asm)
445  # Expand the tabs used for indentation.
446  asm = string.expandtabs(asm, 2)
447  # Strip trailing whitespace.
448  asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm)
449  return asm
450
451# Returns a tuple of a scrub function and a function regex. Scrub function is
452# used to alter function body in some way, for example, remove trailing spaces.
453# Function regex is used to match function name, body, etc. in raw llc output.
454def get_run_handler(triple):
455  target_handlers = {
456      'i686': (scrub_asm_x86, ASM_FUNCTION_X86_RE),
457      'x86': (scrub_asm_x86, ASM_FUNCTION_X86_RE),
458      'i386': (scrub_asm_x86, ASM_FUNCTION_X86_RE),
459      'arm64_32-apple-ios': (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_DARWIN_RE),
460      'arm64_32-apple-watchos2.0.0': (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_DARWIN_RE),
461      'aarch64': (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_RE),
462      'aarch64-apple-darwin': (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_DARWIN_RE),
463      'aarch64-apple-ios': (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_DARWIN_RE),
464      'hexagon': (scrub_asm_hexagon, ASM_FUNCTION_HEXAGON_RE),
465      'r600': (scrub_asm_amdgpu, ASM_FUNCTION_AMDGPU_RE),
466      'amdgcn': (scrub_asm_amdgpu, ASM_FUNCTION_AMDGPU_RE),
467      'arm': (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_RE),
468      'arm64': (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_RE),
469      'arm64e': (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_DARWIN_RE),
470      'arm64ec': (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_RE),
471      'arm64-apple-ios': (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_DARWIN_RE),
472      'armv7-apple-ios' : (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_IOS_RE),
473      'armv7-apple-darwin': (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_DARWIN_RE),
474      'thumb': (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_RE),
475      'thumb-macho': (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_MACHO_RE),
476      'thumbv5-macho': (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_MACHO_RE),
477      'thumbv7s-apple-darwin' : (scrub_asm_arm_eabi, ASM_FUNCTION_THUMBS_DARWIN_RE),
478      'thumbv7-apple-darwin' : (scrub_asm_arm_eabi, ASM_FUNCTION_THUMB_DARWIN_RE),
479      'thumbv7-apple-ios' : (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_IOS_RE),
480      'm68k': (scrub_asm_m68k, ASM_FUNCTION_M68K_RE),
481      'mips': (scrub_asm_mips, ASM_FUNCTION_MIPS_RE),
482      'msp430': (scrub_asm_msp430, ASM_FUNCTION_MSP430_RE),
483      'avr': (scrub_asm_avr, ASM_FUNCTION_AVR_RE),
484      'ppc32': (scrub_asm_powerpc, ASM_FUNCTION_PPC_RE),
485      'powerpc': (scrub_asm_powerpc, ASM_FUNCTION_PPC_RE),
486      'riscv32': (scrub_asm_riscv, ASM_FUNCTION_RISCV_RE),
487      'riscv64': (scrub_asm_riscv, ASM_FUNCTION_RISCV_RE),
488      'lanai': (scrub_asm_lanai, ASM_FUNCTION_LANAI_RE),
489      'sparc': (scrub_asm_sparc, ASM_FUNCTION_SPARC_RE),
490      's390x': (scrub_asm_systemz, ASM_FUNCTION_SYSTEMZ_RE),
491      'wasm32': (scrub_asm_wasm32, ASM_FUNCTION_WASM32_RE),
492      've': (scrub_asm_ve, ASM_FUNCTION_VE_RE),
493      'csky': (scrub_asm_csky, ASM_FUNCTION_CSKY_RE),
494      'nvptx': (scrub_asm_nvptx, ASM_FUNCTION_NVPTX_RE),
495      'loongarch32': (scrub_asm_loongarch, ASM_FUNCTION_LOONGARCH_RE),
496      'loongarch64': (scrub_asm_loongarch, ASM_FUNCTION_LOONGARCH_RE)
497  }
498  handler = None
499  best_prefix = ''
500  for prefix, s in target_handlers.items():
501    if triple.startswith(prefix) and len(prefix) > len(best_prefix):
502      handler = s
503      best_prefix = prefix
504
505  if handler is None:
506    raise KeyError('Triple %r is not supported' % (triple))
507
508  return handler
509
510##### Generator of assembly CHECK lines
511
512def add_checks(output_lines, comment_marker, prefix_list, func_dict,
513               func_name, global_vars_seen_dict, is_filtered):
514  # Label format is based on ASM string.
515  check_label_format = '{} %s-LABEL: %s%s%s'.format(comment_marker)
516  return common.add_checks(output_lines, comment_marker, prefix_list, func_dict,
517                           func_name, check_label_format, True, False,
518                           global_vars_seen_dict, is_filtered=is_filtered)
519