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