]>
Commit | Line | Data |
---|---|---|
1 | #!/usr/bin/python3 | |
2 | # Produce headers of assembly constants from C expressions. | |
3 | # Copyright (C) 2018-2024 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 | # <https://www.gnu.org/licenses/>. | |
19 | ||
20 | # The input to this script looks like: | |
21 | # #cpp-directive ... | |
22 | # NAME1 | |
23 | # NAME2 expression ... | |
24 | # A line giving just a name implies an expression consisting of just that name. | |
25 | ||
26 | import argparse | |
27 | ||
28 | import glibcextract | |
29 | ||
30 | ||
31 | def gen_test(sym_data): | |
32 | """Generate a test for the values of some C constants. | |
33 | ||
34 | The first argument is as for glibcextract.compute_c_consts. | |
35 | ||
36 | """ | |
37 | out_lines = [] | |
38 | for arg in sym_data: | |
39 | if isinstance(arg, str): | |
40 | if arg == 'START': | |
41 | out_lines.append('#include <stdint.h>\n' | |
42 | '#include <stdio.h>\n' | |
43 | '#include <bits/wordsize.h>\n' | |
44 | '#if __WORDSIZE == 64\n' | |
45 | 'typedef uint64_t c_t;\n' | |
46 | '# define U(n) UINT64_C (n)\n' | |
47 | '#else\n' | |
48 | 'typedef uint32_t c_t;\n' | |
49 | '# define U(n) UINT32_C (n)\n' | |
50 | '#endif\n' | |
51 | 'static int\n' | |
52 | 'do_test (void)\n' | |
53 | '{\n' | |
54 | # Compilation test only, using static | |
55 | # assertions. | |
56 | ' return 0;\n' | |
57 | '}\n' | |
58 | '#include <support/test-driver.c>') | |
59 | else: | |
60 | out_lines.append(arg) | |
61 | continue | |
62 | name = arg[0] | |
63 | value = arg[1] | |
64 | out_lines.append('_Static_assert (U (asconst_%s) == (c_t) (%s), ' | |
65 | '"value of %s");' | |
66 | % (name, value, name)) | |
67 | return '\n'.join(out_lines) | |
68 | ||
69 | ||
70 | def main(): | |
71 | """The main entry point.""" | |
72 | parser = argparse.ArgumentParser( | |
73 | description='Produce headers of assembly constants.') | |
74 | parser.add_argument('--cc', metavar='CC', | |
75 | help='C compiler (including options) to use') | |
76 | parser.add_argument('--test', action='store_true', | |
77 | help='Generate test case instead of header') | |
78 | parser.add_argument('--python', action='store_true', | |
79 | help='Generate Python file instead of header') | |
80 | parser.add_argument('sym_file', | |
81 | help='.sym file to process') | |
82 | args = parser.parse_args() | |
83 | sym_data = [] | |
84 | with open(args.sym_file, 'r') as sym_file: | |
85 | started = False | |
86 | for line in sym_file: | |
87 | line = line.strip() | |
88 | if line == '': | |
89 | continue | |
90 | # Pass preprocessor directives through. | |
91 | if line.startswith('#'): | |
92 | sym_data.append(line) | |
93 | continue | |
94 | words = line.split(maxsplit=1) | |
95 | if not started: | |
96 | sym_data.append('START') | |
97 | started = True | |
98 | # Separator. | |
99 | if words[0] == '--': | |
100 | continue | |
101 | name = words[0] | |
102 | value = words[1] if len(words) > 1 else words[0] | |
103 | sym_data.append((name, value)) | |
104 | if not started: | |
105 | sym_data.append('START') | |
106 | if args.test: | |
107 | print(gen_test(sym_data)) | |
108 | elif args.python: | |
109 | consts = glibcextract.compute_c_consts(sym_data, args.cc) | |
110 | print('# GENERATED FILE\n' | |
111 | '\n' | |
112 | '# Constant definitions.\n' | |
113 | '# See gen-as-const.py for details.\n') | |
114 | print(''.join('%s = %s\n' % c for c in sorted(consts.items())), end='') | |
115 | else: | |
116 | consts = glibcextract.compute_c_consts(sym_data, args.cc) | |
117 | print(''.join('#define %s %s\n' % c for c in sorted(consts.items())), end='') | |
118 | ||
119 | if __name__ == '__main__': | |
120 | main() |