OSDN Git Service

Add (very partial) Kate syntax highlighting definition for TableGen
[android-x86/external-llvm.git] / utils / UpdateTestChecks / asm.py
1 import re
2 import sys
3
4 from . import common
5
6 if sys.version_info[0] > 2:
7   class string:
8     expandtabs = str.expandtabs
9 else:
10   import string
11
12 # RegEx: this is where the magic happens.
13
14 ##### Assembly parser
15
16 ASM_FUNCTION_X86_RE = re.compile(
17     r'^_?(?P<func>[^:]+):[ \t]*#+[ \t]*@(?P=func)\n(?:\s*.Lfunc_begin[^:\n]*:\n)?[^:]*?'
18     r'(?P<body>^##?[ \t]+[^:]+:.*?)\s*'
19     r'^\s*(?:[^:\n]+?:\s*\n\s*\.size|\.cfi_endproc|\.globl|\.comm|\.(?:sub)?section|#+ -- End function)',
20     flags=(re.M | re.S))
21
22 ASM_FUNCTION_ARM_RE = re.compile(
23         r'^(?P<func>[0-9a-zA-Z_]+):\n' # f: (name of function)
24         r'\s+\.fnstart\n' # .fnstart
25         r'(?P<body>.*?)\n' # (body of the function)
26         r'.Lfunc_end[0-9]+:', # .Lfunc_end0: or # -- End function
27         flags=(re.M | re.S))
28
29 ASM_FUNCTION_AARCH64_RE = re.compile(
30      r'^_?(?P<func>[^:]+):[ \t]*\/\/[ \t]*@(?P=func)\n'
31      r'(?:[ \t]+.cfi_startproc\n)?'  # drop optional cfi noise 
32      r'(?P<body>.*?)\n'
33      # This list is incomplete
34      r'.Lfunc_end[0-9]+:\n',
35      flags=(re.M | re.S))
36
37 ASM_FUNCTION_AMDGPU_RE = re.compile(
38     r'^_?(?P<func>[^:]+):[ \t]*;+[ \t]*@(?P=func)\n[^:]*?'
39     r'(?P<body>.*?)\n' # (body of the function)
40     # This list is incomplete
41     r'.Lfunc_end[0-9]+:\n',
42     flags=(re.M | re.S))
43
44 ASM_FUNCTION_MIPS_RE = re.compile(
45     r'^_?(?P<func>[^:]+):[ \t]*#+[ \t]*@(?P=func)\n[^:]*?' # f: (name of func)
46     r'(?:^[ \t]+\.(frame|f?mask|set).*?\n)+'  # Mips+LLVM standard asm prologue
47     r'(?P<body>.*?)\n'                        # (body of the function)
48     r'(?:^[ \t]+\.(set|end).*?\n)+'           # Mips+LLVM standard asm epilogue
49     r'(\$|\.L)func_end[0-9]+:\n',             # $func_end0: (mips32 - O32) or
50                                               # .Lfunc_end0: (mips64 - NewABI)
51     flags=(re.M | re.S))
52
53 ASM_FUNCTION_PPC_RE = re.compile(
54     r'^_?(?P<func>[^:]+):[ \t]*#+[ \t]*@(?P=func)\n'
55     r'\.Lfunc_begin[0-9]+:\n'
56     r'(?:[ \t]+.cfi_startproc\n)?'
57     r'(?:\.Lfunc_[gl]ep[0-9]+:\n(?:[ \t]+.*?\n)*)*'
58     r'(?P<body>.*?)\n'
59     # This list is incomplete
60     r'(?:^[ \t]*(?:\.long[ \t]+[^\n]+|\.quad[ \t]+[^\n]+)\n)*'
61     r'.Lfunc_end[0-9]+:\n',
62     flags=(re.M | re.S))
63
64 ASM_FUNCTION_RISCV_RE = re.compile(
65     r'^_?(?P<func>[^:]+):[ \t]*#+[ \t]*@(?P=func)\n[^:]*?'
66     r'(?P<body>^##?[ \t]+[^:]+:.*?)\s*'
67     r'.Lfunc_end[0-9]+:\n',
68     flags=(re.M | re.S))
69
70 ASM_FUNCTION_SPARC_RE = re.compile(
71     r'^_?(?P<func>[^:]+):[ \t]*!+[ \t]*@(?P=func)\n'
72     r'(?P<body>.*?)\s*'
73     r'.Lfunc_end[0-9]+:\n',
74     flags=(re.M | re.S))
75
76 ASM_FUNCTION_SYSTEMZ_RE = re.compile(
77     r'^_?(?P<func>[^:]+):[ \t]*#+[ \t]*@(?P=func)\n'
78     r'[ \t]+.cfi_startproc\n'
79     r'(?P<body>.*?)\n'
80     r'.Lfunc_end[0-9]+:\n',
81     flags=(re.M | re.S))
82
83
84 SCRUB_LOOP_COMMENT_RE = re.compile(
85     r'# =>This Inner Loop Header:.*|# in Loop:.*', flags=re.M)
86
87 SCRUB_X86_SHUFFLES_RE = (
88     re.compile(
89         r'^(\s*\w+) [^#\n]+#+ ((?:[xyz]mm\d+|mem)( \{%k\d+\}( \{z\})?)? = .*)$',
90         flags=re.M))
91 SCRUB_X86_SPILL_RELOAD_RE = (
92     re.compile(
93         r'-?\d+\(%([er])[sb]p\)(.*(?:Spill|Reload))$',
94         flags=re.M))
95 SCRUB_X86_SP_RE = re.compile(r'\d+\(%(esp|rsp)\)')
96 SCRUB_X86_RIP_RE = re.compile(r'[.\w]+\(%rip\)')
97 SCRUB_X86_LCP_RE = re.compile(r'\.LCPI[0-9]+_[0-9]+')
98 SCRUB_X86_RET_RE = re.compile(r'ret[l|q]')
99
100 def scrub_asm_x86(asm, args):
101   # Scrub runs of whitespace out of the assembly, but leave the leading
102   # whitespace in place.
103   asm = common.SCRUB_WHITESPACE_RE.sub(r' ', asm)
104   # Expand the tabs used for indentation.
105   asm = string.expandtabs(asm, 2)
106   # Detect shuffle asm comments and hide the operands in favor of the comments.
107   asm = SCRUB_X86_SHUFFLES_RE.sub(r'\1 {{.*#+}} \2', asm)
108   # Detect stack spills and reloads and hide their exact offset and whether
109   # they used the stack pointer or frame pointer.
110   asm = SCRUB_X86_SPILL_RELOAD_RE.sub(r'{{[-0-9]+}}(%\1{{[sb]}}p)\2', asm)
111   # Generically match the stack offset of a memory operand.
112   asm = SCRUB_X86_SP_RE.sub(r'{{[0-9]+}}(%\1)', asm)
113   # Generically match a RIP-relative memory operand.
114   asm = SCRUB_X86_RIP_RE.sub(r'{{.*}}(%rip)', asm)
115   # Generically match a LCP symbol.
116   asm = SCRUB_X86_LCP_RE.sub(r'{{\.LCPI.*}}', asm)
117   if getattr(args, 'extra_scrub', False):
118     # Avoid generating different checks for 32- and 64-bit because of 'retl' vs 'retq'.
119     asm = SCRUB_X86_RET_RE.sub(r'ret{{[l|q]}}', asm)
120   # Strip kill operands inserted into the asm.
121   asm = common.SCRUB_KILL_COMMENT_RE.sub('', asm)
122   # Strip trailing whitespace.
123   asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm)
124   return asm
125
126 def scrub_asm_amdgpu(asm, args):
127   # Scrub runs of whitespace out of the assembly, but leave the leading
128   # whitespace in place.
129   asm = common.SCRUB_WHITESPACE_RE.sub(r' ', asm)
130   # Expand the tabs used for indentation.
131   asm = string.expandtabs(asm, 2)
132   # Strip trailing whitespace.
133   asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm)
134   return asm
135
136 def scrub_asm_arm_eabi(asm, args):
137   # Scrub runs of whitespace out of the assembly, but leave the leading
138   # whitespace in place.
139   asm = common.SCRUB_WHITESPACE_RE.sub(r' ', asm)
140   # Expand the tabs used for indentation.
141   asm = string.expandtabs(asm, 2)
142   # Strip kill operands inserted into the asm.
143   asm = common.SCRUB_KILL_COMMENT_RE.sub('', asm)
144   # Strip trailing whitespace.
145   asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm)
146   return asm
147
148 def scrub_asm_powerpc64(asm, args):
149   # Scrub runs of whitespace out of the assembly, but leave the leading
150   # whitespace in place.
151   asm = common.SCRUB_WHITESPACE_RE.sub(r' ', asm)
152   # Expand the tabs used for indentation.
153   asm = string.expandtabs(asm, 2)
154   # Stripe unimportant comments
155   asm = SCRUB_LOOP_COMMENT_RE.sub(r'', asm)
156   # Strip trailing whitespace.
157   asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm)
158   return asm
159
160 def scrub_asm_mips(asm, args):
161   # Scrub runs of whitespace out of the assembly, but leave the leading
162   # whitespace in place.
163   asm = common.SCRUB_WHITESPACE_RE.sub(r' ', asm)
164   # Expand the tabs used for indentation.
165   asm = string.expandtabs(asm, 2)
166   # Strip trailing whitespace.
167   asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm)
168   return asm
169
170 def scrub_asm_riscv(asm, args):
171   # Scrub runs of whitespace out of the assembly, but leave the leading
172   # whitespace in place.
173   asm = common.SCRUB_WHITESPACE_RE.sub(r' ', asm)
174   # Expand the tabs used for indentation.
175   asm = string.expandtabs(asm, 2)
176   # Strip trailing whitespace.
177   asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm)
178   return asm
179
180 def scrub_asm_sparc(asm, args):
181   # Scrub runs of whitespace out of the assembly, but leave the leading
182   # whitespace in place.
183   asm = common.SCRUB_WHITESPACE_RE.sub(r' ', asm)
184   # Expand the tabs used for indentation.
185   asm = string.expandtabs(asm, 2)
186   # Strip trailing whitespace.
187   asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm)
188   return asm
189
190 def scrub_asm_systemz(asm, args):
191   # Scrub runs of whitespace out of the assembly, but leave the leading
192   # whitespace in place.
193   asm = common.SCRUB_WHITESPACE_RE.sub(r' ', asm)
194   # Expand the tabs used for indentation.
195   asm = string.expandtabs(asm, 2)
196   # Strip trailing whitespace.
197   asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm)
198   return asm
199
200
201 def build_function_body_dictionary_for_triple(args, raw_tool_output, triple, prefixes, func_dict):
202   target_handlers = {
203       'x86_64': (scrub_asm_x86, ASM_FUNCTION_X86_RE),
204       'i686': (scrub_asm_x86, ASM_FUNCTION_X86_RE),
205       'x86': (scrub_asm_x86, ASM_FUNCTION_X86_RE),
206       'i386': (scrub_asm_x86, ASM_FUNCTION_X86_RE),
207       'aarch64': (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_RE),
208       'r600': (scrub_asm_amdgpu, ASM_FUNCTION_AMDGPU_RE),
209       'amdgcn': (scrub_asm_amdgpu, ASM_FUNCTION_AMDGPU_RE),
210       'arm-eabi': (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_RE),
211       'thumb-eabi': (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_RE),
212       'thumbv6': (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_RE),
213       'thumbv6-eabi': (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_RE),
214       'thumbv6t2': (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_RE),
215       'thumbv6t2-eabi': (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_RE),
216       'thumbv6m': (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_RE),
217       'thumbv6m-eabi': (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_RE),
218       'thumbv7': (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_RE),
219       'thumbv7-eabi': (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_RE),
220       'thumbv7m': (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_RE),
221       'thumbv7m-eabi': (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_RE),
222       'thumbv8-eabi': (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_RE),
223       'thumbv8m.base': (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_RE),
224       'thumbv8m.main': (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_RE),
225       'armv6': (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_RE),
226       'armv7': (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_RE),
227       'armv7-eabi': (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_RE),
228       'armeb-eabi': (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_RE),
229       'armv7eb-eabi': (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_RE),
230       'armv7eb': (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_RE),
231       'mips': (scrub_asm_mips, ASM_FUNCTION_MIPS_RE),
232       'powerpc64': (scrub_asm_powerpc64, ASM_FUNCTION_PPC_RE),
233       'powerpc64le': (scrub_asm_powerpc64, ASM_FUNCTION_PPC_RE),
234       'riscv32': (scrub_asm_riscv, ASM_FUNCTION_RISCV_RE),
235       'riscv64': (scrub_asm_riscv, ASM_FUNCTION_RISCV_RE),
236       'sparc': (scrub_asm_sparc, ASM_FUNCTION_SPARC_RE),
237       'sparcv9': (scrub_asm_sparc, ASM_FUNCTION_SPARC_RE),
238       's390x': (scrub_asm_systemz, ASM_FUNCTION_SYSTEMZ_RE),
239   }
240   handlers = None
241   for prefix, s in target_handlers.items():
242     if triple.startswith(prefix):
243       handlers = s
244       break
245   else:
246     raise KeyError('Triple %r is not supported' % (triple))
247
248   scrubber, function_re = handlers
249   common.build_function_body_dictionary(
250           function_re, scrubber, [args], raw_tool_output, prefixes,
251           func_dict, args.verbose)
252
253 ##### Generator of assembly CHECK lines
254
255 def add_asm_checks(output_lines, comment_marker, prefix_list, func_dict, func_name):
256   # Label format is based on ASM string.
257   check_label_format = '{} %s-LABEL: %s:'.format(comment_marker)
258   common.add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name, check_label_format, True, False)