gas2nasm.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. #!/usr/bin/env python -tt
  2. # -*- python -*-
  3. # Convert gas testsuite file to NASM test asm file
  4. # usage >
  5. # python gas2nasm.py -i input_gas_file -o output_nasm_file -b bits
  6. # e.g. python gas2nasm.py -i x86-64-avx512f-intel.d -o avx512f.asm -b 64
  7. import sys
  8. import os
  9. import optparse
  10. import re
  11. def setup():
  12. parser = optparse.OptionParser()
  13. parser.add_option('-i', dest='input', action='store',
  14. default="",
  15. help='Name for input gas testsuite file.')
  16. parser.add_option('-o', dest='output', action='store',
  17. default="",
  18. help='Name for output NASM test asm file.')
  19. parser.add_option('-b', dest='bits', action='store',
  20. default="",
  21. help='Bits for output ASM file.')
  22. parser.add_option('-r', dest='raw_output', action='store',
  23. default="",
  24. help='Name for raw output bytes in text')
  25. (options, args) = parser.parse_args()
  26. return options
  27. def read(options):
  28. with open(options.input, 'rb') as f:
  29. recs = []
  30. for line in f:
  31. if line[0] == '[':
  32. d = []
  33. strr = line[16:].partition(' ')
  34. if strr[1] == '':
  35. strr = line[16:].partition('\t')
  36. l = strr[0].strip()
  37. r = strr[2].strip()
  38. d.append(l)
  39. d.append(r)
  40. recs.append(d)
  41. return recs
  42. def commas(recs):
  43. replace_tbl = {' PTR':'', '\\':'', 'MM':'', 'XWORD':'OWORD'}
  44. reccommas = []
  45. for insn in recs:
  46. new = []
  47. byte = '0x' + insn[0].replace(' ', ', 0x')
  48. for rep in replace_tbl.keys():
  49. insn[1] = insn[1].replace(rep, replace_tbl[rep])
  50. mnemonic = insn[1]
  51. # gas size specifier for gather and scatter insturctions seems wrong. just remove them.
  52. if 'gather' in insn[1] or 'scatter' in insn[1]:
  53. mnemonic = mnemonic.replace('ZWORD', '')
  54. new.append(byte)
  55. new.append(mnemonic)
  56. reccommas.append(new)
  57. return reccommas
  58. # The spaces reserved here can be adjusted according to the output string length.
  59. # maxlen printed out at the end of the process will give a hint for it.
  60. outstrfmt = "testcase\t{ %-70s }, { %-60s }\n"
  61. macro = "%macro testcase 2\n %ifdef BIN\n db %1\n %endif\n %ifdef SRC\n %2\n %endif\n%endmacro\n\n\n"
  62. def write(data, options):
  63. if options.output:
  64. with open(options.output, 'wb') as out:
  65. out.write(macro)
  66. if options.bits:
  67. out.write('bits ' + options.bits + '\n\n')
  68. for insn in data:
  69. outstr = outstrfmt % tuple(insn)
  70. out.write(outstr)
  71. def write_rawbytes(data, options):
  72. if options.raw_output:
  73. with open(options.raw_output, 'wb') as out:
  74. for insn in data:
  75. out.write(insn[0] + '\n')
  76. if __name__ == "__main__":
  77. options = setup()
  78. recs = read(options)
  79. write_rawbytes(recs, options)
  80. recs = commas(recs)
  81. write(recs, options)
  82. maxlen = [0,0,0,0,0,0,0,0]
  83. for insn in recs:
  84. #print insn[0] + '\t<-\t' + insn[1]
  85. print outstrfmt[:-1] % tuple(insn)
  86. for i, strstr in enumerate(insn):
  87. if maxlen[i] < len(strstr): maxlen[i] = len(strstr)
  88. print maxlen