2013-08-21 14:50:26 +08:00
|
|
|
#!/usr/bin/env python -tt
|
|
|
|
# -*- python -*-
|
|
|
|
# Convert gas testsuite file to NASM test asm file
|
|
|
|
# usage >
|
|
|
|
# python gas2nasm.py -i input_gas_file -o output_nasm_file -b bits
|
|
|
|
# e.g. python gas2nasm.py -i x86-64-avx512f-intel.d -o avx512f.asm -b 64
|
|
|
|
|
|
|
|
import sys
|
|
|
|
import os
|
|
|
|
import optparse
|
|
|
|
import re
|
|
|
|
|
|
|
|
def setup():
|
|
|
|
parser = optparse.OptionParser()
|
|
|
|
parser.add_option('-i', dest='input', action='store',
|
|
|
|
default="",
|
|
|
|
help='Name for input gas testsuite file.')
|
|
|
|
parser.add_option('-o', dest='output', action='store',
|
|
|
|
default="",
|
|
|
|
help='Name for output NASM test asm file.')
|
|
|
|
parser.add_option('-b', dest='bits', action='store',
|
|
|
|
default="",
|
|
|
|
help='Bits for output ASM file.')
|
2013-08-24 09:40:49 +08:00
|
|
|
parser.add_option('-r', dest='raw_output', action='store',
|
|
|
|
default="",
|
|
|
|
help='Name for raw output bytes in text')
|
2013-08-21 14:50:26 +08:00
|
|
|
(options, args) = parser.parse_args()
|
|
|
|
return options
|
|
|
|
|
|
|
|
def read(options):
|
|
|
|
with open(options.input, 'rb') as f:
|
|
|
|
recs = []
|
|
|
|
for line in f:
|
|
|
|
if line[0] == '[':
|
|
|
|
d = []
|
|
|
|
strr = line[16:].partition(' ')
|
|
|
|
if strr[1] == '':
|
|
|
|
strr = line[16:].partition('\t')
|
|
|
|
l = strr[0].strip()
|
|
|
|
r = strr[2].strip()
|
2013-09-07 12:22:18 +08:00
|
|
|
d.append(l)
|
|
|
|
d.append(r)
|
|
|
|
recs.append(d)
|
2013-08-21 14:50:26 +08:00
|
|
|
return recs
|
|
|
|
|
|
|
|
def commas(recs):
|
|
|
|
replace_tbl = {' PTR':'', '\\':'', 'MM':'', '{':'\{', '}':'\}', 'XWORD':'OWORD'}
|
|
|
|
reccommas = []
|
|
|
|
for insn in recs:
|
|
|
|
new = []
|
|
|
|
byte = '0x' + insn[0].replace(' ', ', 0x')
|
|
|
|
for rep in replace_tbl.keys():
|
|
|
|
insn[1] = insn[1].replace(rep, replace_tbl[rep])
|
|
|
|
mnemonic = insn[1]
|
|
|
|
|
|
|
|
# gas size specifier for gather and scatter insturctions seems wrong. just remove them.
|
|
|
|
if 'gather' in insn[1] or 'scatter' in insn[1]:
|
|
|
|
mnemonic = mnemonic.replace('ZWORD', '')
|
|
|
|
|
|
|
|
new.append(byte)
|
|
|
|
new.append(mnemonic)
|
|
|
|
reccommas.append(new)
|
|
|
|
return reccommas
|
|
|
|
|
|
|
|
# The spaces reserved here can be adjusted according to the output string length.
|
|
|
|
# maxlen printed out at the end of the process will give a hint for it.
|
|
|
|
outstrfmt = "testcase\t{ %-70s }, { %-60s }\n"
|
|
|
|
|
|
|
|
macro = "%macro testcase 2\n %ifdef BIN\n db %1\n %endif\n %ifdef SRC\n %2\n %endif\n%endmacro\n\n\n"
|
|
|
|
|
|
|
|
def write(data, options):
|
|
|
|
if options.output:
|
|
|
|
with open(options.output, 'wb') as out:
|
|
|
|
out.write(macro)
|
|
|
|
if options.bits:
|
|
|
|
out.write('bits ' + options.bits + '\n\n')
|
|
|
|
for insn in data:
|
|
|
|
outstr = outstrfmt % tuple(insn)
|
|
|
|
out.write(outstr)
|
|
|
|
|
2013-08-24 09:40:49 +08:00
|
|
|
def write_rawbytes(data, options):
|
|
|
|
if options.raw_output:
|
|
|
|
with open(options.raw_output, 'wb') as out:
|
|
|
|
for insn in data:
|
|
|
|
out.write(insn[0] + '\n')
|
|
|
|
|
2013-08-21 14:50:26 +08:00
|
|
|
if __name__ == "__main__":
|
|
|
|
options = setup()
|
|
|
|
recs = read(options)
|
|
|
|
|
2013-08-24 09:40:49 +08:00
|
|
|
write_rawbytes(recs, options)
|
|
|
|
|
2013-08-21 14:50:26 +08:00
|
|
|
recs = commas(recs)
|
|
|
|
|
|
|
|
write(recs, options)
|
|
|
|
|
|
|
|
maxlen = [0,0,0,0,0,0,0,0]
|
|
|
|
for insn in recs:
|
|
|
|
#print insn[0] + '\t<-\t' + insn[1]
|
|
|
|
print outstrfmt[:-1] % tuple(insn)
|
|
|
|
for i, strstr in enumerate(insn):
|
|
|
|
if maxlen[i] < len(strstr): maxlen[i] = len(strstr)
|
|
|
|
|
|
|
|
print maxlen
|