3 Copyright 2013-15 ARM Limited and Contributors.
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
8 * Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
13 * Neither the name of ARM Limited nor the
14 names of its contributors may be used to endorse or promote products
15 derived from this software without specific prior written permission.
17 THIS SOFTWARE IS PROVIDED BY ARM LIMITED AND CONTRIBUTORS "AS IS" AND
18 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 DISCLAIMED. IN NO EVENT SHALL ARM LIMITED AND CONTRIBUTORS BE LIABLE FOR ANY
21 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.'''
28'''convert GAS arm assembly to Clang's integrated-as'''
31''' parse .qn .dn .req directive for arm assembly
34def parse_alias(inlines):
36 alias_exp = re.compile(
r" *"
37 r"(?P<alias>[_a-zA-Z0-9]+)"
39 r"(?P<value>[a-zA-Z0-9\[\]]+)"
41 global_exp = re.compile(
r"\.global")
48 if global_exp.search(line):
51 result = alias_exp.search(line)
53 alias = result.group(
'alias')
54 value = result.group(
'value')
55 alias_dics[func_count][alias] = value
62 if global_exp.search(line):
64 for alias
in alias_dics[func_count]:
65 alias_str =
"\\b"+alias+
"\\b"
66 alias_exp = re.compile(alias_str)
67 line = alias_exp.sub(alias_dics[func_count][alias], line)
68 line_result1.append(line)
72 alias_exp = re.compile(
r"\.(qn|dn|req|unreq)")
73 for line
in line_result1:
74 if not alias_exp.search(line):
75 line_result2.append(line)
79''' parse .qn .dn .req directive for arm assembly
81 this is for fft module's new format: in the new format,
82 all aliases are defined at the begin of files and all functions
83 share one set of defines.
85def parse_alias_fft(inlines):
87 alias_exp = re.compile(
r" *"
88 r"(?P<alias>[_a-zA-Z0-9]+)"
90 r"(?P<value>[a-zA-Z0-9\[\]]+)"
94 result = alias_exp.search(line)
96 alias = result.group(
'alias')
97 value = result.group(
'value')
98 aliases[alias] = value
104 for alias
in aliases:
105 alias_str =
"\\b"+alias+
"\\b"
106 alias_exp = re.compile(alias_str)
107 line = alias_exp.sub(aliases[alias], line)
108 line_result1.append(line)
112 alias_exp = re.compile(
r"\.(qn|dn|req|unreq)")
113 for line
in line_result1:
114 if not alias_exp.search(line):
115 line_result2.append(line)
119'''add .F32 to some instructions for Clang's as doesn't support register with
120 datatype, such as VADD Q0.F32, Q1.F32, Q2.F32'''
122 instructions = [
'VADD',
'VSUB',
'VLD1',
'VLD2',
'VMUL',
'VMLA',
'VMLS',
123 'VZIP',
'VST1',
'VST2',
'VPADD',
'VEXT',
'VREV64',
127 for instruction
in instructions:
128 instruction_exp = re.compile(instruction)
129 instruction_f32_exp = re.compile(instruction +
"\\.[Ff]32")
131 if instruction_exp.search(line)
and \
132 not instruction_f32_exp.search(line):
133 line = instruction_exp.sub(instruction +
".F32", line)
134 line_result.append(line)
137'''remove .end instruction'''
138def remove_end(inlines):
139 end_exp = re.compile(
r"\.end\b")
142 if not end_exp.search(line):
143 line_result.append(line)
146'''expan ldr rx, =label for Clang, this method has *not* been used in current
147assembly convertion, Clang doesn't support this pseudo-instruction'''
148def expan_ldr1(inlines):
151 ldr_exp = re.compile(
r"\s*LDR.*="
152 r"(?P<label>[_a-zA-Z0-9]+)")
154 result = ldr_exp.search(line)
156 label = result.group(
'label')
157 if label
not in labels:
167 ldr_exp = re.compile(
"=" + label)
168 if ldr_exp.search(line):
169 result_line = ldr_exp.sub(
"L" + label, line)
171 lines_result1.append(result_line)
174 lines_result1.append(
" .text\n")
175 lines_result1.append(
" .align 2\n")
177 lines_result1.append(
"L" + label +
":\n")
178 lines_result1.append(
" .long " + label +
"\n")
182 for line
in lines_result1:
185 extern_exp = re.compile(
r"\s*\.extern\s*" + label)
186 if extern_exp.search(line):
189 lines_result2.append(line)
193'''expan ldr rx, =label for Clang, Clang doesn't support this
195def expan_ldr2(inlines):
198 ldr_exp = re.compile(
r"\s*(LDR|ldr)\s*(?P<reg>[a-zA-Z0-9]+),\s*="
199 r"(?P<label>[_a-zA-Z0-9]+)")
201 result = ldr_exp.search(line)
203 label = result.group(
'label')
204 if label
not in labels:
215 result = ldr_exp.search(line)
217 reg = result.group(
'reg')
218 result_line =
" MOVW "\
219 + reg +
",:lower16:(L" + label +\
220 "$non_lazy_ptr - (LPC0_" + str(count) +
" + 4))\n" +\
222 ",:upper16:(L" + label +
"$non_lazy_ptr - (LPC0_" +\
223 str(count) +
" + 4))\n" +
"LPC0_" + str(count) +
":\n"\
226 reg +
",[" + reg +
"]\n"
229 lines_result1.append(result_line)
232 lines_result1.append(
" .section __DATA,__nl_symbol_ptr,\
233 non_lazy_symbol_pointers\n")
234 lines_result1.append(
" .align 2\n")
236 lines_result1.append(
"L" + label +
"$non_lazy_ptr:\n")
237 lines_result1.append(
" .indirect_symbol " + label +
"\n")
238 lines_result1.append(
" .long 0\n")
239 lines_result1.append(
"\n .subsections_via_symbols\n")
243 for line
in lines_result1:
246 extern_exp = re.compile(
r"\s*\.extern\s*" + label)
247 if extern_exp.search(line):
250 lines_result2.append(line)
254'''add prefix 'L' to local label '''
255def add_Llabel(inlines):
259 glabel_exp = re.compile(
r"\s*\.globa?l\s*"
260 r"(?P<glabel>\b[_a-zA-Z0-9]+\b)")
261 result = glabel_exp.search(line)
263 glabels.append(result.group(
'glabel'))
269 llabel_exp = re.compile(
r"(?P<llabel>^[._a-zA-Z0-9]+):")
270 result = llabel_exp.search(line)
272 llabel = result.group(
'llabel')
273 leading_L_exp = re.compile(
r"^L.*")
274 if llabel
not in glabels
and not leading_L_exp.search(llabel):
275 llabels.append(llabel)
282 for llabel
in llabels:
283 new_llabel = llabel.replace(
'.L',
'')
285 if new_llabel != llabel:
286 llabel_exp = re.compile(llabel.replace(
'.',
'\\.'))
288 llabel_exp = re.compile(
"\\b" + llabel +
"\\b")
290 if llabel_exp.search(line):
291 result_line = llabel_exp.sub(
"L" + new_llabel, line)
293 result_lines.append(result_line)
298 fft_file_names = [
'NE10_fft_float32.neon.s',
299 'NE10_fft_int16.neon.s',
300 'NE10_fft_int32.neon.s']
301 if len(sys.argv) < 3:
302 print "Usage: convert.py <input file> <output file>"
305 infilename = sys.argv[1]
306 outfilename = sys.argv[2]
307 infile = open(infilename,
'r')
309 for line
in infile.readlines():
314 if os.path.basename(infilename)
in fft_file_names:
315 result = parse_alias_fft(lines)
317 result = parse_alias(lines)
318 result = add_f32(result)
319 result = remove_end(result)
320 result = add_Llabel(result)
321 result = expan_ldr2(result)
323 outfile = open(outfilename,
'w')