xref: /llvm-project/llvm/utils/UpdateTestChecks/asm.py (revision 6025ee79ae9a9b90e53fc5ebd5d780da0cd45b4c)
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[^$]+\$local:\n)?'      # drop .L<func>$local:
20    r'(?:[ \t]+.cfi_startproc\n|.seh_proc[^\n]+\n)?'  # drop optional cfi
21    r'(?P<body>^##?[ \t]+[^:]+:.*?)\s*'
22    r'^\s*(?:[^:\n]+?:\s*\n\s*\.size|\.cfi_endproc|\.globl|\.comm|\.(?:sub)?section|#+ -- End function)',
23    flags=(re.M | re.S))
24
25ASM_FUNCTION_ARM_RE = re.compile(
26        r'^(?P<func>[0-9a-zA-Z_]+):\n' # f: (name of function)
27        r'\s+\.fnstart\n' # .fnstart
28        r'(?P<body>.*?)\n' # (body of the function)
29        r'.Lfunc_end[0-9]+:', # .Lfunc_end0: or # -- End function
30        flags=(re.M | re.S))
31
32ASM_FUNCTION_AARCH64_RE = re.compile(
33     r'^_?(?P<func>[^:]+):[ \t]*\/\/[ \t]*@"?(?P=func)"?( (Function|Tail Call))?\n'
34     r'(?:[ \t]+.cfi_startproc\n)?'  # drop optional cfi noise
35     r'(?P<body>.*?)\n'
36     # This list is incomplete
37     r'.Lfunc_end[0-9]+:\n',
38     flags=(re.M | re.S))
39
40ASM_FUNCTION_AMDGPU_RE = re.compile(
41    r'^_?(?P<func>[^:]+):[ \t]*;+[ \t]*@"?(?P=func)"?\n[^:]*?'
42    r'(?P<body>.*?)\n' # (body of the function)
43    # This list is incomplete
44    r'^\s*(\.Lfunc_end[0-9]+:\n|\.section)',
45    flags=(re.M | re.S))
46
47ASM_FUNCTION_HEXAGON_RE = re.compile(
48    r'^_?(?P<func>[^:]+):[ \t]*//[ \t]*@"?(?P=func)"?\n[^:]*?'
49    r'(?P<body>.*?)\n' # (body of the function)
50    # This list is incomplete
51    r'.Lfunc_end[0-9]+:\n',
52    flags=(re.M | re.S))
53
54ASM_FUNCTION_M68K_RE = re.compile(
55    r'^_?(?P<func>[^:]+):[ \t]*;[ \t]*@"?(?P=func)"?\n'
56    r'(?P<body>.*?)\s*' # (body of the function)
57    r'.Lfunc_end[0-9]+:\n',
58    flags=(re.M | re.S))
59
60ASM_FUNCTION_MIPS_RE = re.compile(
61    r'^_?(?P<func>[^:]+):[ \t]*#+[ \t]*@"?(?P=func)"?\n[^:]*?' # f: (name of func)
62    r'(?:\s*\.?Ltmp[^:\n]*:\n)?[^:]*?'        # optional .Ltmp<N> for EH
63    r'(?:^[ \t]+\.(frame|f?mask|set).*?\n)+'  # Mips+LLVM standard asm prologue
64    r'(?P<body>.*?)\n'                        # (body of the function)
65    # Mips+LLVM standard asm epilogue
66    r'(?:(^[ \t]+\.set[^\n]*?\n)*^[ \t]+\.end.*?\n)'
67    r'(\$|\.L)func_end[0-9]+:\n',             # $func_end0: (mips32 - O32) or
68                                              # .Lfunc_end0: (mips64 - NewABI)
69    flags=(re.M | re.S))
70
71ASM_FUNCTION_MSP430_RE = re.compile(
72    r'^_?(?P<func>[^:]+):[ \t]*;+[ \t]*@"?(?P=func)"?\n[^:]*?'
73    r'(?P<body>.*?)\n'
74    r'(\$|\.L)func_end[0-9]+:\n',             # $func_end0:
75    flags=(re.M | re.S))
76
77ASM_FUNCTION_AVR_RE = re.compile(
78    r'^_?(?P<func>[^:]+):[ \t]*;+[ \t]*@"?(?P=func)"?\n[^:]*?'
79    r'(?P<body>.*?)\n'
80    r'.Lfunc_end[0-9]+:\n',
81    flags=(re.M | re.S))
82
83ASM_FUNCTION_PPC_RE = re.compile(
84    r'#[ \-\t]*Begin function (?P<func>[^.:]+)\n'
85    r'.*?'
86    r'^[_.]?(?P=func):(?:[ \t]*#+[ \t]*@"?(?P=func)"?)?\n'
87    r'(?:^[^#]*\n)*'
88    r'(?P<body>.*?)\n'
89    # This list is incomplete
90    r'(?:^[ \t]*(?:\.(?:long|quad|v?byte)[ \t]+[^\n]+)\n)*'
91    r'(?:\.Lfunc_end|L\.\.(?P=func))[0-9]+:\n',
92    flags=(re.M | re.S))
93
94ASM_FUNCTION_RISCV_RE = re.compile(
95    r'^_?(?P<func>[^:]+):[ \t]*#+[ \t]*@"?(?P=func)"?\n'
96    r'(?:\s*\.?L(?P=func)\$local:\n)?'  # optional .L<func>$local: due to -fno-semantic-interposition
97    r'(?:\s*\.?Lfunc_begin[^:\n]*:\n)?[^:]*?'
98    r'(?P<body>^##?[ \t]+[^:]+:.*?)\s*'
99    r'.Lfunc_end[0-9]+:\n',
100    flags=(re.M | re.S))
101
102ASM_FUNCTION_LANAI_RE = re.compile(
103    r'^_?(?P<func>[^:]+):[ \t]*!+[ \t]*@"?(?P=func)"?\n'
104    r'(?:[ \t]+.cfi_startproc\n)?'  # drop optional cfi noise
105    r'(?P<body>.*?)\s*'
106    r'.Lfunc_end[0-9]+:\n',
107    flags=(re.M | re.S))
108
109ASM_FUNCTION_SPARC_RE = re.compile(
110    r'^_?(?P<func>[^:]+):[ \t]*!+[ \t]*@"?(?P=func)"?\n'
111    r'(?P<body>.*?)\s*'
112    r'.Lfunc_end[0-9]+:\n',
113    flags=(re.M | re.S))
114
115ASM_FUNCTION_SYSTEMZ_RE = re.compile(
116    r'^_?(?P<func>[^:]+):[ \t]*#+[ \t]*@"?(?P=func)"?\n'
117    r'[ \t]+.cfi_startproc\n'
118    r'(?P<body>.*?)\n'
119    r'.Lfunc_end[0-9]+:\n',
120    flags=(re.M | re.S))
121
122ASM_FUNCTION_AARCH64_DARWIN_RE = re.compile(
123     r'^_(?P<func>[^:]+):[ \t]*;[ \t]@"?(?P=func)"?\n'
124     r'([ \t]*.cfi_startproc\n[\s]*)?'
125     r'(?P<body>.*?)'
126     r'([ \t]*.cfi_endproc\n[\s]*)?'
127     r'^[ \t]*;[ \t]--[ \t]End[ \t]function',
128     flags=(re.M | re.S))
129
130ASM_FUNCTION_ARM_DARWIN_RE = re.compile(
131     r'^[ \t]*\.globl[ \t]*_(?P<func>[^ \t])[ \t]*@[ \t]--[ \t]Begin[ \t]function[ \t]"?(?P=func)"?'
132     r'(?P<directives>.*?)'
133     r'^_(?P=func):\n[ \t]*'
134     r'(?P<body>.*?)'
135     r'^[ \t]*@[ \t]--[ \t]End[ \t]function',
136     flags=(re.M | re.S ))
137
138ASM_FUNCTION_ARM_MACHO_RE = re.compile(
139     r'^_(?P<func>[^:]+):[ \t]*\n'
140     r'([ \t]*.cfi_startproc\n[ \t]*)?'
141     r'(?P<body>.*?)\n'
142     r'[ \t]*\.cfi_endproc\n',
143     flags=(re.M | re.S))
144
145ASM_FUNCTION_THUMBS_DARWIN_RE = re.compile(
146     r'^_(?P<func>[^:]+):\n'
147     r'(?P<body>.*?)\n'
148     r'[ \t]*\.data_region\n',
149     flags=(re.M | re.S))
150
151ASM_FUNCTION_THUMB_DARWIN_RE = re.compile(
152     r'^_(?P<func>[^:]+):\n'
153     r'(?P<body>.*?)\n'
154     r'^[ \t]*@[ \t]--[ \t]End[ \t]function',
155     flags=(re.M | re.S))
156
157ASM_FUNCTION_ARM_IOS_RE = re.compile(
158     r'^_(?P<func>[^:]+):\n'
159     r'(?P<body>.*?)'
160     r'^[ \t]*@[ \t]--[ \t]End[ \t]function',
161     flags=(re.M | re.S))
162
163ASM_FUNCTION_WASM32_RE = re.compile(
164    r'^_?(?P<func>[^:]+):[ \t]*#+[ \t]*@"?(?P=func)"?\n'
165    r'(?P<body>.*?)\n'
166    r'^\s*(\.Lfunc_end[0-9]+:\n|end_function)',
167    flags=(re.M | re.S))
168
169ASM_FUNCTION_VE_RE = re.compile(
170    r'^_?(?P<func>[^:]+):[ \t]*#+[ \t]*@(?P=func)\n'
171    r'(?P<body>^##?[ \t]+[^:]+:.*?)\s*'
172    r'.Lfunc_end[0-9]+:\n',
173    flags=(re.M | re.S))
174
175ASM_FUNCTION_CSKY_RE = re.compile(
176    r'^_?(?P<func>[^:]+):[ \t]*#+[ \t]*@(?P=func)\n(?:\s*\.?Lfunc_begin[^:\n]*:\n)?[^:]*?'
177    r'(?P<body>^##?[ \t]+[^:]+:.*?)\s*'
178    r'.Lfunc_end[0-9]+:\n',
179    flags=(re.M | re.S))
180
181SCRUB_X86_SHUFFLES_RE = (
182    re.compile(
183        r'^(\s*\w+) [^#\n]+#+ ((?:[xyz]mm\d+|mem)( \{%k\d+\}( \{z\})?)? = .*)$',
184        flags=re.M))
185
186SCRUB_X86_SHUFFLES_NO_MEM_RE = (
187    re.compile(
188        r'^(\s*\w+) [^#\n]+#+ ((?:[xyz]mm\d+|mem)( \{%k\d+\}( \{z\})?)? = (?!.*(?:mem)).*)$',
189        flags=re.M))
190
191SCRUB_X86_SPILL_RELOAD_RE = (
192    re.compile(
193        r'-?\d+\(%([er])[sb]p\)(.*(?:Spill|Reload))$',
194        flags=re.M))
195SCRUB_X86_SP_RE = re.compile(r'\d+\(%(esp|rsp)\)')
196SCRUB_X86_RIP_RE = re.compile(r'[.\w]+\(%rip\)')
197SCRUB_X86_LCP_RE = re.compile(r'\.?LCPI[0-9]+_[0-9]+')
198SCRUB_X86_RET_RE = re.compile(r'ret[l|q]')
199
200def scrub_asm_x86(asm, args):
201  # Scrub runs of whitespace out of the assembly, but leave the leading
202  # whitespace in place.
203  asm = common.SCRUB_WHITESPACE_RE.sub(r' ', asm)
204  # Expand the tabs used for indentation.
205  asm = string.expandtabs(asm, 2)
206
207  # Detect shuffle asm comments and hide the operands in favor of the comments.
208  if getattr(args, 'no_x86_scrub_mem_shuffle', True):
209    asm = SCRUB_X86_SHUFFLES_NO_MEM_RE.sub(r'\1 {{.*#+}} \2', asm)
210  else:
211    asm = SCRUB_X86_SHUFFLES_RE.sub(r'\1 {{.*#+}} \2', asm)
212
213  # Detect stack spills and reloads and hide their exact offset and whether
214  # they used the stack pointer or frame pointer.
215  asm = SCRUB_X86_SPILL_RELOAD_RE.sub(r'{{[-0-9]+}}(%\1{{[sb]}}p)\2', asm)
216  if getattr(args, 'x86_scrub_sp', True):
217    # Generically match the stack offset of a memory operand.
218    asm = SCRUB_X86_SP_RE.sub(r'{{[0-9]+}}(%\1)', asm)
219  if getattr(args, 'x86_scrub_rip', False):
220    # Generically match a RIP-relative memory operand.
221    asm = SCRUB_X86_RIP_RE.sub(r'{{.*}}(%rip)', asm)
222  # Generically match a LCP symbol.
223  asm = SCRUB_X86_LCP_RE.sub(r'{{\.?LCPI[0-9]+_[0-9]+}}', asm)
224  if getattr(args, 'extra_scrub', False):
225    # Avoid generating different checks for 32- and 64-bit because of 'retl' vs 'retq'.
226    asm = SCRUB_X86_RET_RE.sub(r'ret{{[l|q]}}', asm)
227  # Strip kill operands inserted into the asm.
228  asm = common.SCRUB_KILL_COMMENT_RE.sub('', asm)
229  # Strip trailing whitespace.
230  asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm)
231  return asm
232
233def scrub_asm_amdgpu(asm, args):
234  # Scrub runs of whitespace out of the assembly, but leave the leading
235  # whitespace in place.
236  asm = common.SCRUB_WHITESPACE_RE.sub(r' ', asm)
237  # Expand the tabs used for indentation.
238  asm = string.expandtabs(asm, 2)
239  # Strip trailing whitespace.
240  asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm)
241  return asm
242
243def scrub_asm_arm_eabi(asm, args):
244  # Scrub runs of whitespace out of the assembly, but leave the leading
245  # whitespace in place.
246  asm = common.SCRUB_WHITESPACE_RE.sub(r' ', asm)
247  # Expand the tabs used for indentation.
248  asm = string.expandtabs(asm, 2)
249  # Strip kill operands inserted into the asm.
250  asm = common.SCRUB_KILL_COMMENT_RE.sub('', asm)
251  # Strip trailing whitespace.
252  asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm)
253  return asm
254
255def scrub_asm_hexagon(asm, args):
256  # Scrub runs of whitespace out of the assembly, but leave the leading
257  # whitespace in place.
258  asm = common.SCRUB_WHITESPACE_RE.sub(r' ', asm)
259  # Expand the tabs used for indentation.
260  asm = string.expandtabs(asm, 2)
261  # Strip trailing whitespace.
262  asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm)
263  return asm
264
265def scrub_asm_powerpc(asm, args):
266  # Scrub runs of whitespace out of the assembly, but leave the leading
267  # whitespace in place.
268  asm = common.SCRUB_WHITESPACE_RE.sub(r' ', asm)
269  # Expand the tabs used for indentation.
270  asm = string.expandtabs(asm, 2)
271  # Strip unimportant comments, but leave the token '#' in place.
272  asm = common.SCRUB_LOOP_COMMENT_RE.sub(r'#', asm)
273  # Strip trailing whitespace.
274  asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm)
275  # Strip the tailing token '#', except the line only has token '#'.
276  asm = common.SCRUB_TAILING_COMMENT_TOKEN_RE.sub(r'', asm)
277  return asm
278
279def scrub_asm_m68k(asm, args):
280  # Scrub runs of whitespace out of the assembly, but leave the leading
281  # whitespace in place.
282  asm = common.SCRUB_WHITESPACE_RE.sub(r' ', asm)
283  # Expand the tabs used for indentation.
284  asm = string.expandtabs(asm, 2)
285  # Strip trailing whitespace.
286  asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm)
287  return asm
288
289def scrub_asm_mips(asm, args):
290  # Scrub runs of whitespace out of the assembly, but leave the leading
291  # whitespace in place.
292  asm = common.SCRUB_WHITESPACE_RE.sub(r' ', asm)
293  # Expand the tabs used for indentation.
294  asm = string.expandtabs(asm, 2)
295  # Strip trailing whitespace.
296  asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm)
297  return asm
298
299def scrub_asm_msp430(asm, args):
300  # Scrub runs of whitespace out of the assembly, but leave the leading
301  # whitespace in place.
302  asm = common.SCRUB_WHITESPACE_RE.sub(r' ', asm)
303  # Expand the tabs used for indentation.
304  asm = string.expandtabs(asm, 2)
305  # Strip trailing whitespace.
306  asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm)
307  return asm
308
309def scrub_asm_avr(asm, args):
310  # Scrub runs of whitespace out of the assembly, but leave the leading
311  # whitespace in place.
312  asm = common.SCRUB_WHITESPACE_RE.sub(r' ', asm)
313  # Expand the tabs used for indentation.
314  asm = string.expandtabs(asm, 2)
315  # Strip trailing whitespace.
316  asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm)
317  return asm
318
319def scrub_asm_riscv(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_lanai(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_sparc(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_systemz(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_wasm32(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_ve(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_csky(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 kill operands inserted into the asm.
386  asm = common.SCRUB_KILL_COMMENT_RE.sub('', asm)
387  # Strip trailing whitespace.
388  asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm)
389  return asm
390
391def get_triple_from_march(march):
392  triples = {
393      'amdgcn': 'amdgcn',
394      'r600': 'r600',
395      'mips': 'mips',
396      'sparc': 'sparc',
397      'hexagon': 'hexagon',
398      've': 've',
399  }
400  for prefix, triple in triples.items():
401    if march.startswith(prefix):
402      return triple
403  print("Cannot find a triple. Assume 'x86'", file=sys.stderr)
404  return 'x86'
405
406def get_run_handler(triple):
407  target_handlers = {
408      'i686': (scrub_asm_x86, ASM_FUNCTION_X86_RE),
409      'x86': (scrub_asm_x86, ASM_FUNCTION_X86_RE),
410      'i386': (scrub_asm_x86, ASM_FUNCTION_X86_RE),
411      'arm64_32-apple-ios': (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_DARWIN_RE),
412      'aarch64': (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_RE),
413      'aarch64-apple-darwin': (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_DARWIN_RE),
414      'aarch64-apple-ios': (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_DARWIN_RE),
415      'hexagon': (scrub_asm_hexagon, ASM_FUNCTION_HEXAGON_RE),
416      'r600': (scrub_asm_amdgpu, ASM_FUNCTION_AMDGPU_RE),
417      'amdgcn': (scrub_asm_amdgpu, ASM_FUNCTION_AMDGPU_RE),
418      'arm': (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_RE),
419      'arm64': (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_RE),
420      'arm64e': (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_DARWIN_RE),
421      'arm64-apple-ios': (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_DARWIN_RE),
422      'armv7-apple-ios' : (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_IOS_RE),
423      'armv7-apple-darwin': (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_DARWIN_RE),
424      'thumb': (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_RE),
425      'thumb-macho': (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_MACHO_RE),
426      'thumbv5-macho': (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_MACHO_RE),
427      'thumbv7s-apple-darwin' : (scrub_asm_arm_eabi, ASM_FUNCTION_THUMBS_DARWIN_RE),
428      'thumbv7-apple-darwin' : (scrub_asm_arm_eabi, ASM_FUNCTION_THUMB_DARWIN_RE),
429      'thumbv7-apple-ios' : (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_IOS_RE),
430      'm68k': (scrub_asm_m68k, ASM_FUNCTION_M68K_RE),
431      'mips': (scrub_asm_mips, ASM_FUNCTION_MIPS_RE),
432      'msp430': (scrub_asm_msp430, ASM_FUNCTION_MSP430_RE),
433      'avr': (scrub_asm_avr, ASM_FUNCTION_AVR_RE),
434      'ppc32': (scrub_asm_powerpc, ASM_FUNCTION_PPC_RE),
435      'powerpc': (scrub_asm_powerpc, ASM_FUNCTION_PPC_RE),
436      'riscv32': (scrub_asm_riscv, ASM_FUNCTION_RISCV_RE),
437      'riscv64': (scrub_asm_riscv, ASM_FUNCTION_RISCV_RE),
438      'lanai': (scrub_asm_lanai, ASM_FUNCTION_LANAI_RE),
439      'sparc': (scrub_asm_sparc, ASM_FUNCTION_SPARC_RE),
440      's390x': (scrub_asm_systemz, ASM_FUNCTION_SYSTEMZ_RE),
441      'wasm32': (scrub_asm_wasm32, ASM_FUNCTION_WASM32_RE),
442      've': (scrub_asm_ve, ASM_FUNCTION_VE_RE),
443      'csky': (scrub_asm_csky, ASM_FUNCTION_CSKY_RE),
444  }
445  handler = None
446  best_prefix = ''
447  for prefix, s in target_handlers.items():
448    if triple.startswith(prefix) and len(prefix) > len(best_prefix):
449      handler = s
450      best_prefix = prefix
451
452  if handler is None:
453    raise KeyError('Triple %r is not supported' % (triple))
454
455  return handler
456
457##### Generator of assembly CHECK lines
458
459def add_asm_checks(output_lines, comment_marker, prefix_list, func_dict, func_name):
460  # Label format is based on ASM string.
461  check_label_format = '{} %s-LABEL: %s%s:'.format(comment_marker)
462  global_vars_seen_dict = {}
463  common.add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name, check_label_format, True, False, global_vars_seen_dict)
464