1# This Source Code Form is subject to the terms of the Mozilla Public
2# License, v. 2.0. If a copy of the MPL was not distributed with this
3# file, You can obtain one at http://mozilla.org/MPL/2.0/.
4
5# This script generates jit/LOpcodesGenerated.h (list of LIR instructions)
6# from LIR files.
7
8import re
9
10HEADER_TEMPLATE = """\
11/* This Source Code Form is subject to the terms of the Mozilla Public
12 * License, v. 2.0. If a copy of the MPL was not distributed with this
13 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
14
15#ifndef %(includeguard)s
16#define %(includeguard)s
17
18/* This file is generated by jit/GenerateOpcodeFiles.py. Do not edit! */
19
20#define %(listname)s(_) \\
21%(ops)s
22
23#endif // %(includeguard)s
24"""
25
26
27def get_opcodes(inputs, pat):
28    # Preserve the original order. Use a set to detect duplicates.
29    ops = []
30    ops_set = set()
31    for inputfile in inputs:
32        for line in open(inputfile):
33            match = pat.match(line)
34            if match:
35                op = match.group("name")
36                if op in ops_set:
37                    raise Exception("Duplicate opcode {} in {}".format(op, inputfile))
38                ops.append(op)
39                ops_set.add(op)
40    assert len(ops) == len(ops_set)
41    return ops
42
43
44def generate_header(c_out, inputs, pat, includeguard, listname):
45    ops = get_opcodes(inputs, pat)
46    ops_string = "\\\n".join(["_(" + op + ")" for op in ops])
47    c_out.write(
48        HEADER_TEMPLATE
49        % {
50            "ops": ops_string,
51            "includeguard": includeguard,
52            "listname": listname,
53        }
54    )
55
56
57def generate_lir_header(c_out, *inputs):
58    pat = re.compile(r"^\s*LIR_HEADER\((?P<name>\w+)\);?$")
59    generate_header(c_out, inputs, pat, "jit_LOpcodesGenerated_h", "LIR_OPCODE_LIST")
60