gen-as-const.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #!/usr/bin/python3
  2. # Produce headers of assembly constants from C expressions.
  3. # Copyright (C) 2018-2019 Free Software Foundation, Inc.
  4. # This file is part of the GNU C Library.
  5. #
  6. # The GNU C Library is free software; you can redistribute it and/or
  7. # modify it under the terms of the GNU Lesser General Public
  8. # License as published by the Free Software Foundation; either
  9. # version 2.1 of the License, or (at your option) any later version.
  10. #
  11. # The GNU C Library is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. # Lesser General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU Lesser General Public
  17. # License along with the GNU C Library; if not, see
  18. # <http://www.gnu.org/licenses/>.
  19. # The input to this script looks like:
  20. # #cpp-directive ...
  21. # NAME1
  22. # NAME2 expression ...
  23. # A line giving just a name implies an expression consisting of just that name.
  24. import argparse
  25. import glibcextract
  26. def gen_test(sym_data):
  27. """Generate a test for the values of some C constants.
  28. The first argument is as for glibcextract.compute_c_consts.
  29. """
  30. out_lines = []
  31. for arg in sym_data:
  32. if isinstance(arg, str):
  33. if arg == 'START':
  34. out_lines.append('#include <stdint.h>\n'
  35. '#include <stdio.h>\n'
  36. '#include <bits/wordsize.h>\n'
  37. '#if __WORDSIZE == 64\n'
  38. 'typedef uint64_t c_t;\n'
  39. '# define U(n) UINT64_C (n)\n'
  40. '#else\n'
  41. 'typedef uint32_t c_t;\n'
  42. '# define U(n) UINT32_C (n)\n'
  43. '#endif\n'
  44. 'static int\n'
  45. 'do_test (void)\n'
  46. '{\n'
  47. # Compilation test only, using static
  48. # assertions.
  49. ' return 0;\n'
  50. '}\n'
  51. '#include <support/test-driver.c>')
  52. else:
  53. out_lines.append(arg)
  54. continue
  55. name = arg[0]
  56. value = arg[1]
  57. out_lines.append('_Static_assert (U (asconst_%s) == (c_t) (%s), '
  58. '"value of %s");'
  59. % (name, value, name))
  60. return '\n'.join(out_lines)
  61. def main():
  62. """The main entry point."""
  63. parser = argparse.ArgumentParser(
  64. description='Produce headers of assembly constants.')
  65. parser.add_argument('--cc', metavar='CC',
  66. help='C compiler (including options) to use')
  67. parser.add_argument('--test', action='store_true',
  68. help='Generate test case instead of header')
  69. parser.add_argument('--python', action='store_true',
  70. help='Generate Python file instead of header')
  71. parser.add_argument('sym_file',
  72. help='.sym file to process')
  73. args = parser.parse_args()
  74. sym_data = []
  75. with open(args.sym_file, 'r') as sym_file:
  76. started = False
  77. for line in sym_file:
  78. line = line.strip()
  79. if line == '':
  80. continue
  81. # Pass preprocessor directives through.
  82. if line.startswith('#'):
  83. sym_data.append(line)
  84. continue
  85. words = line.split(maxsplit=1)
  86. if not started:
  87. sym_data.append('START')
  88. started = True
  89. # Separator.
  90. if words[0] == '--':
  91. continue
  92. name = words[0]
  93. value = words[1] if len(words) > 1 else words[0]
  94. sym_data.append((name, value))
  95. if not started:
  96. sym_data.append('START')
  97. if args.test:
  98. print(gen_test(sym_data))
  99. elif args.python:
  100. consts = glibcextract.compute_c_consts(sym_data, args.cc)
  101. print('# GENERATED FILE\n'
  102. '\n'
  103. '# Constant definitions.\n'
  104. '# See gen-as-const.py for details.\n')
  105. print(''.join('%s = %s\n' % c for c in sorted(consts.items())), end='')
  106. else:
  107. consts = glibcextract.compute_c_consts(sym_data, args.cc)
  108. print(''.join('#define %s %s\n' % c for c in sorted(consts.items())), end='')
  109. if __name__ == '__main__':
  110. main()