649 lines · python
1from __future__ import print_function2import re3import sys4 5from . import common6 7if sys.version_info[0] > 2:8 9 class string:10 expandtabs = str.expandtabs11 12else:13 import string14 15# RegEx: this is where the magic happens.16 17##### Assembly parser18#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"23 24ASM_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>$local28 r"(?:[ \t]*(?:\.cfi_startproc|\.cfi_personality|\.cfi_lsda|\.seh_proc|\.seh_handler)\b[^\n]*\n)*" # drop optional cfi29 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),32)33 34ASM_FUNCTION_ARM_RE = re.compile(35 r'^(?P<func>[0-9a-zA-Z_$]+):[ \t]*(@+[ \t]*@"?(?P=func)"?)?\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>$local38 r"\s+\.fnstart\n" # .fnstart39 r"(?P<body>.*?)" # (body of the function)40 r"^.Lfunc_end[0-9]+:", # .Lfunc_end0: or # -- End function41 flags=(re.M | re.S),42)43 44ASM_FUNCTION_AARCH64_RE = re.compile(45 r'^(?P<func>_?[a-zA-Z][^:]*):[ \t]*(\/\/[ \t]*@"?(?P=func)"?)?( (Function|Tail Call))?\n'46 r"(?:[ \t]+.cfi_startproc\n)?" # drop optional cfi noise47 r"(?P<body>.*?)"48 # This list is incomplete49 r"^\s*(\.Lfunc_end[0-9]+:|// -- End function)",50 flags=(re.M | re.S),51)52 53ASM_FUNCTION_AMDGPU_RE = re.compile(54 r"\.type\s+(_|\.L)?(?P<func>[^,\n]+),@function\n"55 r"(^\s*\.amdgpu_hsa_kernel (?P=func)\n)?"56 r'^(_|\.L)?(?P=func):(?:[ \t]*;+[ \t]*@"?(?P=func)"?)?\n'57 r"(?P<body>.*?)\n" # (body of the function)58 # This list is incomplete59 r"^\s*(\.Lfunc_end[0-9]+:\n|\.section)",60 flags=(re.M | re.S),61)62 63ASM_FUNCTION_BPF_RE = re.compile(64 r'^_?(?P<func>[^:]+):[ \t]*#+[ \t]*@"?(?P=func)"?\n'65 r"(?:[ \t]+.cfi_startproc\n|.seh_proc[^\n]+\n)?" # drop optional cfi66 r"(?P<body>.*?)\s*"67 r".Lfunc_end[0-9]+:\n",68 flags=(re.M | re.S),69)70 71ASM_FUNCTION_HEXAGON_RE = re.compile(72 r'^_?(?P<func>[^:]+):[ \t]*//[ \t]*@"?(?P=func)"?\n[^:]*?'73 r"(?P<body>.*?)\n" # (body of the function)74 # This list is incomplete75 r".Lfunc_end[0-9]+:\n",76 flags=(re.M | re.S),77)78 79ASM_FUNCTION_M68K_RE = re.compile(80 r'^_?(?P<func>[^:]+):[ \t]*;[ \t]*@"?(?P=func)"?\n'81 r'(?:\.L(?P=func)\$local:\n)?' # drop .L<func>$local:82 r'(?:[ \t]+\.type[ \t]+\.L(?P=func)\$local,@function\n)?' # drop .type .L<func>$local,@function83 r'(?P<body>.*?)\s*' # (body of the function)84 r'.Lfunc_end[0-9]+:\n',85 flags=(re.M | re.S))86 87ASM_FUNCTION_MIPS_RE = re.compile(88 r'^_?(?P<func>[^:]+):[ \t]*#+[ \t]*@"?(?P=func)"?\n[^:]*?' # f: (name of func)89 r"(?:\s*\.?Ltmp[^:\n]*:\n)?[^:]*?" # optional .Ltmp<N> for EH90 r"(?:^[ \t]+\.(frame|f?mask|set).*?\n)+" # Mips+LLVM standard asm prologue91 r"(?P<body>.*?)\n" # (body of the function)92 # Mips+LLVM standard asm epilogue93 r"(?:(^[ \t]+\.set[^\n]*?\n)*^[ \t]+\.end.*?\n)"94 r"(\$|\.L)func_end[0-9]+:\n", # $func_end0: (mips32 - O32) or95 # .Lfunc_end0: (mips64 - NewABI)96 flags=(re.M | re.S),97)98 99ASM_FUNCTION_MSP430_RE = re.compile(100 r'^_?(?P<func>[^:]+):[ \t]*;+[ \t]*@"?(?P=func)"?\n[^:]*?'101 r"(?P<body>.*?)\n"102 r"(\$|\.L)func_end[0-9]+:\n", # $func_end0:103 flags=(re.M | re.S),104)105 106ASM_FUNCTION_AVR_RE = re.compile(107 r'^_?(?P<func>[^:]+):[ \t]*;+[ \t]*@"?(?P=func)"?\n[^:]*?'108 r"(?P<body>.*?)\n"109 r".Lfunc_end[0-9]+:\n",110 flags=(re.M | re.S),111)112 113ASM_FUNCTION_PPC_RE = re.compile(114 r"#[ \-\t]*Begin function (?P<func>[^.:]+)\n"115 r".*?"116 r'^[_.]?(?P=func):(?:[ \t]*#+[ \t]*@"?(?P=func)"?)?\n'117 r"(?:^[^#]*\n)*"118 r"(?P<body>.*?)\n"119 # This list is incomplete120 r"(?:^[ \t]*(?:\.(?:long|quad|v?byte)[ \t]+[^\n]+)\n)*"121 r"(?:\.Lfunc_end|L\.\.(?P=func))[0-9]+:\n",122 flags=(re.M | re.S),123)124 125ASM_FUNCTION_RISCV_RE = re.compile(126 r'^_?(?P<func>[^:]+):[ \t]*#+[ \t]*@"?(?P=func)"?\n'127 r"(?:\s*\.?L(?P=func)\$local:\n)?" # optional .L<func>$local: due to -fno-semantic-interposition128 r"(?:\s*\.type\s+\.?L(?P=func)\$local,@function\n)?" # optional .type .L<func>$local129 r"(?:\s*\.?Lfunc_begin[^:\n]*:\n)?[^:]*?"130 r"(?P<body>^##?[ \t]+[^:]+:.*?)\s*"131 r".Lfunc_end[0-9]+:\n",132 flags=(re.M | re.S),133)134 135ASM_FUNCTION_LANAI_RE = re.compile(136 r'^_?(?P<func>[^:]+):[ \t]*!+[ \t]*@"?(?P=func)"?\n'137 r"(?:[ \t]+.cfi_startproc\n)?" # drop optional cfi noise138 r"(?P<body>.*?)\s*"139 r".Lfunc_end[0-9]+:\n",140 flags=(re.M | re.S),141)142 143ASM_FUNCTION_SPARC_RE = re.compile(144 r'^_?(?P<func>[^:]+):[ \t]*!+[ \t]*@"?(?P=func)"?\n'145 r"(?P<body>.*?)\s*"146 r".Lfunc_end[0-9]+:\n",147 flags=(re.M | re.S),148)149 150ASM_FUNCTION_SYSTEMZ_RE = re.compile(151 r'^_?(?P<func>[^:]+):[ \t]*#+[ \t]*@"?(?P=func)"?\n'152 r"(?:[ \t]+.cfi_startproc\n)?"153 r"(?P<body>.*?)\n"154 r".Lfunc_end[0-9]+:\n",155 flags=(re.M | re.S),156)157 158ASM_FUNCTION_AARCH64_DARWIN_RE = re.compile(159 r'^_(?P<func>[^:]+):[ \t]*;[ \t]@"?(?P=func)"?\n'160 r"([ \t]*.cfi_startproc\n[\s]*)?"161 r"(?P<body>.*?)"162 r"([ \t]*.cfi_endproc\n[\s]*)?"163 r"^[ \t]*;[ \t]--[ \t]End[ \t]function",164 flags=(re.M | re.S),165)166 167ASM_FUNCTION_ARM_DARWIN_RE = re.compile(168 r"^[ \t]*\.globl[ \t]*_(?P<func>[^ \t]+)[ \t]*\@[ \t]*--[ \t]Begin[ \t]function[ \t](?P=func)\n"169 r"(?P<directives>.*?)"170 r"^_(?P=func):.*?\n"171 r"(?P<body>.*?)(?=^[ \t]*@[ \t]--[ \t]End[ \t]function)",172 flags=(re.M | re.S),173)174 175ASM_FUNCTION_ARM_MACHO_RE = re.compile(176 r'^_(?P<func>[^:]+):[ \t]*(@[ \t]@"?(?P=func)"?)?\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),181)182 183ASM_FUNCTION_THUMBS_DARWIN_RE = re.compile(184 r'^_(?P<func>[^:]+):[ \t]*(@[ \t]@"?(?P=func)"?)?\n'185 r"(?P<body>.*?)\n"186 r"[ \t]*\.data_region\n",187 flags=(re.M | re.S),188)189 190ASM_FUNCTION_THUMB_DARWIN_RE = re.compile(191 r'^_(?P<func>[^:]+):[ \t]*(@[ \t]@"?(?P=func)"?)?\n'192 r"(?P<body>.*?)\n"193 r"^[ \t]*@[ \t]--[ \t]End[ \t]function",194 flags=(re.M | re.S),195)196 197ASM_FUNCTION_ARM_IOS_RE = re.compile(198 r'^_(?P<func>[^:]+):[ \t]*(@[ \t]@"?(?P=func)"?)?\n'199 r"(?P<body>.*?)"200 r"^[ \t]*@[ \t]--[ \t]End[ \t]function",201 flags=(re.M | re.S),202)203 204ASM_FUNCTION_WASM_RE = re.compile(205 r'^_?(?P<func>[^:]+):[ \t]*#+[ \t]*@"?(?P=func)"?\n'206 r"(?P<body>.*?)\n"207 r"^\s*(\.Lfunc_end[0-9]+:\n|end_function)",208 flags=(re.M | re.S),209)210 211# We parse the function name from OpName, and grab the variable name 'var'212# for this function. Then we match that when the variable is assigned with213# OpFunction and match its body.214ASM_FUNCTION_SPIRV_RE = re.compile(215 r'OpName (?P<var>%[0-9]+) "(?P<func>[^"]+)(?P<func_name_separator>)".*(?P<body>(?P=var) = OpFunction.+?OpFunctionEnd)',216 flags=(re.M | re.S),217)218 219ASM_FUNCTION_VE_RE = re.compile(220 r"^_?(?P<func>[^:]+):[ \t]*#+[ \t]*@(?P=func)\n"221 r"(?:\s*\.?L(?P=func)\$local:\n)?" # optional .L<func>$local: due to -fno-semantic-interposition222 r"(?:\s*\.type\s+\.?L(?P=func)\$local,@function\n)?" # optional .type .L<func>$local223 r"(?:\s*\.?Lfunc_begin[^:\n]*:\n)?[^:]*?"224 r"(?P<body>^##?[ \t]+[^:]+:.*?)\s*"225 r".Lfunc_end[0-9]+:\n",226 flags=(re.M | re.S),227)228 229ASM_FUNCTION_XTENSA_RE = re.compile(230 r"^(?P<func>[^:]+): +# @(?P=func)\n(?P<body>.*?)\n\.Lfunc_end\d+:\n",231 flags=(re.M | re.S),232)233 234ASM_FUNCTION_CSKY_RE = re.compile(235 r"^_?(?P<func>[^:]+):[ \t]*#+[ \t]*@(?P=func)\n(?:\s*\.?Lfunc_begin[^:\n]*:\n)?[^:]*?"236 r"(?P<body>^##?[ \t]+[^:]+:.*?)\s*"237 r".Lfunc_end[0-9]+:\n",238 flags=(re.M | re.S),239)240 241ASM_FUNCTION_NVPTX_RE = re.compile(242 # function attributes and retval243 # .visible .func (.param .align 16 .b8 func_retval0[32])244 # r'^(\.visible\s+)?\.func\s+(\([^\)]*\)\s*)?'245 r"^(\.(func|visible|weak|entry|noreturn|extern)\s+)+(\([^\)]*\)\s*)?"246 # function name247 r"(?P<func>[^\(\n]+)"248 # function name separator (opening brace)249 r"(?P<func_name_separator>\()"250 # function parameters251 # (252 # .param .align 16 .b8 callee_St8x4_param_0[32]253 # ) // -- Begin function callee_St8x4254 r"[^\)]*\)(\s*//[^\n]*)?\n"255 # function body256 r"(?P<body>.*?)\n"257 # function body end marker258 r"\s*// -- End function",259 flags=(re.M | re.S),260)261 262ASM_FUNCTION_LOONGARCH_RE = re.compile(263 r'^_?(?P<func>[^:]+):[ \t]*#+[ \t]*@"?(?P=func)"?\n'264 r"(?:\s*\.?Lfunc_begin[^:\n]*:\n)?[^:]*?"265 r"(?P<body>^##?[ \t]+[^:]+:.*?)\s*"266 r".Lfunc_end[0-9]+:\n",267 flags=(re.M | re.S),268)269 270SCRUB_X86_SHUFFLES_RE = re.compile(271 r"^(\s*\w+) [^#\n]+#+ ((?:[xyz]mm\d+|mem)( \{%k\d+\}( \{z\})?)? = .*)$", flags=re.M272)273 274SCRUB_X86_SHUFFLES_NO_MEM_RE = re.compile(275 r"^(\s*\w+) [^#\n]+#+ ((?:[xyz]mm\d+|mem)( \{%k\d+\}( \{z\})?)? = (?!.*(?:mem)).*)$",276 flags=re.M,277)278 279SCRUB_X86_SPILL_RELOAD_RE = re.compile(280 r"-?\d+\(%([er])[sb]p\)(.*(?:Spill|Reload))$", flags=re.M281)282SCRUB_X86_SP_RE = re.compile(r"\d+\(%(esp|rsp)\)")283SCRUB_X86_RIP_RE = re.compile(r"[.\w]+\(%rip\)")284SCRUB_X86_LCP_RE = re.compile(r"\.?LCPI[0-9]+_[0-9]+")285SCRUB_X86_RET_RE = re.compile(r"ret[l|q]")286 287 288def scrub_asm_x86(asm, args):289 # Scrub runs of whitespace out of the assembly, but leave the leading290 # whitespace in place.291 asm = common.SCRUB_WHITESPACE_RE.sub(r" ", asm)292 # Expand the tabs used for indentation.293 asm = string.expandtabs(asm, 2)294 295 # Detect shuffle asm comments and hide the operands in favor of the comments.296 if getattr(args, "no_x86_scrub_mem_shuffle", True):297 asm = SCRUB_X86_SHUFFLES_NO_MEM_RE.sub(r"\1 {{.*#+}} \2", asm)298 else:299 asm = SCRUB_X86_SHUFFLES_RE.sub(r"\1 {{.*#+}} \2", asm)300 301 # Detect stack spills and reloads and hide their exact offset and whether302 # they used the stack pointer or frame pointer.303 asm = SCRUB_X86_SPILL_RELOAD_RE.sub(r"{{[-0-9]+}}(%\1{{[sb]}}p)\2", asm)304 if getattr(args, "x86_scrub_sp", True):305 # Generically match the stack offset of a memory operand.306 asm = SCRUB_X86_SP_RE.sub(r"{{[0-9]+}}(%\1)", asm)307 if getattr(args, "x86_scrub_rip", False):308 # Generically match a RIP-relative memory operand.309 asm = SCRUB_X86_RIP_RE.sub(r"{{.*}}(%rip)", asm)310 # Generically match a LCP symbol.311 asm = SCRUB_X86_LCP_RE.sub(r"{{\.?LCPI[0-9]+_[0-9]+}}", asm)312 if getattr(args, "extra_scrub", False):313 # Avoid generating different checks for 32- and 64-bit because of 'retl' vs 'retq'.314 asm = SCRUB_X86_RET_RE.sub(r"ret{{[l|q]}}", asm)315 # Strip kill operands inserted into the asm.316 asm = common.SCRUB_KILL_COMMENT_RE.sub("", asm)317 # Strip trailing whitespace.318 asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r"", asm)319 return asm320 321 322def scrub_asm_amdgpu(asm, args):323 # Scrub runs of whitespace out of the assembly, but leave the leading324 # 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 trailing whitespace.329 asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r"", asm)330 return asm331 332 333def scrub_asm_arm_eabi(asm, args):334 # Scrub runs of whitespace out of the assembly, but leave the leading335 # whitespace in place.336 asm = common.SCRUB_WHITESPACE_RE.sub(r" ", asm)337 # Expand the tabs used for indentation.338 asm = string.expandtabs(asm, 2)339 # Strip kill operands inserted into the asm.340 asm = common.SCRUB_KILL_COMMENT_RE.sub("", asm)341 # Strip trailing whitespace.342 asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r"", asm)343 return asm344 345 346def scrub_asm_bpf(asm, args):347 # Scrub runs of whitespace out of the assembly, but leave the leading348 # 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 asm355 356 357def scrub_asm_hexagon(asm, args):358 # Scrub runs of whitespace out of the assembly, but leave the leading359 # 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 trailing whitespace.364 asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r"", asm)365 return asm366 367 368def scrub_asm_powerpc(asm, args):369 # Scrub runs of whitespace out of the assembly, but leave the leading370 # whitespace in place.371 asm = common.SCRUB_WHITESPACE_RE.sub(r" ", asm)372 # Expand the tabs used for indentation.373 asm = string.expandtabs(asm, 2)374 # Strip unimportant comments, but leave the token '#' in place.375 asm = common.SCRUB_LOOP_COMMENT_RE.sub(r"#", asm)376 # Strip trailing whitespace.377 asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r"", asm)378 # Strip the tailing token '#', except the line only has token '#'.379 asm = common.SCRUB_TAILING_COMMENT_TOKEN_RE.sub(r"", asm)380 return asm381 382 383def scrub_asm_m68k(asm, args):384 # Scrub runs of whitespace out of the assembly, but leave the leading385 # 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 asm392 393 394def scrub_asm_mips(asm, args):395 # Scrub runs of whitespace out of the assembly, but leave the leading396 # 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 asm403 404 405def scrub_asm_msp430(asm, args):406 # Scrub runs of whitespace out of the assembly, but leave the leading407 # 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 asm414 415 416def scrub_asm_avr(asm, args):417 # Scrub runs of whitespace out of the assembly, but leave the leading418 # 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 asm425 426 427def scrub_asm_riscv(asm, args):428 # Scrub runs of whitespace out of the assembly, but leave the leading429 # 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 asm436 437 438def scrub_asm_lanai(asm, args):439 # Scrub runs of whitespace out of the assembly, but leave the leading440 # 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 asm447 448 449def scrub_asm_sparc(asm, args):450 # Scrub runs of whitespace out of the assembly, but leave the leading451 # 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 asm458 459 460def scrub_asm_spirv(asm, args):461 # Scrub runs of whitespace out of the assembly, but leave the leading462 # 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 asm469 470 471def scrub_asm_systemz(asm, args):472 # Scrub runs of whitespace out of the assembly, but leave the leading473 # 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 asm480 481 482def scrub_asm_wasm(asm, args):483 # Scrub runs of whitespace out of the assembly, but leave the leading484 # 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 asm491 492 493def scrub_asm_ve(asm, args):494 # Scrub runs of whitespace out of the assembly, but leave the leading495 # 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 trailing whitespace.500 asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r"", asm)501 return asm502 503 504def scrub_asm_xtensa(asm, args):505 # Scrub runs of whitespace out of the assembly, but leave the leading506 # whitespace in place.507 asm = common.SCRUB_WHITESPACE_RE.sub(r" ", asm)508 # Expand the tabs used for indentation.509 asm = string.expandtabs(asm, 2)510 # Strip trailing whitespace.511 asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r"", asm)512 return asm513 514 515def scrub_asm_csky(asm, args):516 # Scrub runs of whitespace out of the assembly, but leave the leading517 # whitespace in place.518 asm = common.SCRUB_WHITESPACE_RE.sub(r" ", asm)519 # Expand the tabs used for indentation.520 asm = string.expandtabs(asm, 2)521 # Strip kill operands inserted into the asm.522 asm = common.SCRUB_KILL_COMMENT_RE.sub("", asm)523 # Strip trailing whitespace.524 asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r"", asm)525 return asm526 527 528def scrub_asm_nvptx(asm, args):529 # Scrub runs of whitespace out of the assembly, but leave the leading530 # whitespace in place.531 asm = common.SCRUB_WHITESPACE_RE.sub(r" ", asm)532 # Expand the tabs used for indentation.533 asm = string.expandtabs(asm, 2)534 # Strip trailing whitespace.535 asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r"", asm)536 return asm537 538 539def scrub_asm_loongarch(asm, args):540 # Scrub runs of whitespace out of the assembly, but leave the leading541 # whitespace in place.542 asm = common.SCRUB_WHITESPACE_RE.sub(r" ", asm)543 # Expand the tabs used for indentation.544 asm = string.expandtabs(asm, 2)545 # Strip trailing whitespace.546 asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r"", asm)547 return asm548 549 550# Returns a tuple of a scrub function and a function regex. Scrub function is551# used to alter function body in some way, for example, remove trailing spaces.552# Function regex is used to match function name, body, etc. in raw llc output.553def get_run_handler(triple):554 target_handlers = {555 "i686": (scrub_asm_x86, ASM_FUNCTION_X86_RE),556 "x86": (scrub_asm_x86, ASM_FUNCTION_X86_RE),557 "i386": (scrub_asm_x86, ASM_FUNCTION_X86_RE),558 "arm64_32": (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_DARWIN_RE),559 "aarch64": (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_RE),560 "aarch64-apple-darwin": (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_DARWIN_RE),561 "aarch64-apple-ios": (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_DARWIN_RE),562 "aarch64-apple-macosx": (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_DARWIN_RE),563 "bpf": (scrub_asm_bpf, ASM_FUNCTION_BPF_RE),564 "bpfel": (scrub_asm_bpf, ASM_FUNCTION_BPF_RE),565 "bpfeb": (scrub_asm_bpf, ASM_FUNCTION_BPF_RE),566 "hexagon": (scrub_asm_hexagon, ASM_FUNCTION_HEXAGON_RE),567 "r600": (scrub_asm_amdgpu, ASM_FUNCTION_AMDGPU_RE),568 "amdgcn": (scrub_asm_amdgpu, ASM_FUNCTION_AMDGPU_RE),569 "arm": (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_RE),570 "arm64": (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_RE),571 "arm64e": (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_DARWIN_RE),572 "arm64ec": (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_RE),573 "arm64-apple-darwin": (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_DARWIN_RE),574 "arm64-apple-ios": (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_DARWIN_RE),575 "arm64-apple-macosx": (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_DARWIN_RE),576 "armv7-apple-ios": (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_IOS_RE),577 "armv7-apple-darwin": (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_DARWIN_RE),578 "armv7k-apple-watchos": (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_DARWIN_RE),579 "thumbv7k-apple-watchos": (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_DARWIN_RE),580 "thumb": (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_RE),581 "thumb-macho": (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_MACHO_RE),582 "thumbv5-macho": (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_MACHO_RE),583 "thumbv7s-apple-darwin": (scrub_asm_arm_eabi, ASM_FUNCTION_THUMBS_DARWIN_RE),584 "thumbv7-apple-darwin": (scrub_asm_arm_eabi, ASM_FUNCTION_THUMB_DARWIN_RE),585 "thumbv7-apple-ios": (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_IOS_RE),586 "m68k": (scrub_asm_m68k, ASM_FUNCTION_M68K_RE),587 "mips": (scrub_asm_mips, ASM_FUNCTION_MIPS_RE),588 "msp430": (scrub_asm_msp430, ASM_FUNCTION_MSP430_RE),589 "avr": (scrub_asm_avr, ASM_FUNCTION_AVR_RE),590 "ppc32": (scrub_asm_powerpc, ASM_FUNCTION_PPC_RE),591 "ppc64": (scrub_asm_powerpc, ASM_FUNCTION_PPC_RE),592 "powerpc": (scrub_asm_powerpc, ASM_FUNCTION_PPC_RE),593 "riscv32": (scrub_asm_riscv, ASM_FUNCTION_RISCV_RE),594 "riscv64": (scrub_asm_riscv, ASM_FUNCTION_RISCV_RE),595 "lanai": (scrub_asm_lanai, ASM_FUNCTION_LANAI_RE),596 "sparc": (scrub_asm_sparc, ASM_FUNCTION_SPARC_RE),597 "spirv": (scrub_asm_spirv, ASM_FUNCTION_SPIRV_RE),598 "spirv32": (scrub_asm_spirv, ASM_FUNCTION_SPIRV_RE),599 "spirv64": (scrub_asm_spirv, ASM_FUNCTION_SPIRV_RE),600 "s390x": (scrub_asm_systemz, ASM_FUNCTION_SYSTEMZ_RE),601 "wasm32": (scrub_asm_wasm, ASM_FUNCTION_WASM_RE),602 "wasm64": (scrub_asm_wasm, ASM_FUNCTION_WASM_RE),603 "ve": (scrub_asm_ve, ASM_FUNCTION_VE_RE),604 "xtensa": (scrub_asm_xtensa, ASM_FUNCTION_XTENSA_RE),605 "csky": (scrub_asm_csky, ASM_FUNCTION_CSKY_RE),606 "nvptx": (scrub_asm_nvptx, ASM_FUNCTION_NVPTX_RE),607 "loongarch32": (scrub_asm_loongarch, ASM_FUNCTION_LOONGARCH_RE),608 "loongarch64": (scrub_asm_loongarch, ASM_FUNCTION_LOONGARCH_RE),609 }610 handler = None611 best_prefix = ""612 for prefix, s in target_handlers.items():613 if triple.startswith(prefix) and len(prefix) > len(best_prefix):614 handler = s615 best_prefix = prefix616 617 if handler is None:618 raise KeyError("Triple %r is not supported" % (triple))619 620 return handler621 622 623##### Generator of assembly CHECK lines624 625 626def add_checks(627 output_lines,628 comment_marker,629 prefix_list,630 func_dict,631 func_name,632 ginfo: common.GeneralizerInfo,633 global_vars_seen_dict,634 is_filtered,635):636 # Label format is based on ASM string.637 check_label_format = "{} %s-LABEL: %s%s%s%s".format(comment_marker)638 return common.add_checks(639 output_lines,640 comment_marker,641 prefix_list,642 func_dict,643 func_name,644 check_label_format,645 ginfo,646 global_vars_seen_dict,647 is_filtered=is_filtered,648 )649