brintos

brintos / llvm-project-archived public Read only

0
0
Text · 23.3 KiB · 8237786 Raw
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