1e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar#!/usr/bin/env python
2e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar
3e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbardef analyze_match_table(path):
4e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar    # Extract the instruction table.
5e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar    data = open(path).read()
6e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar    start = data.index("static const MatchEntry MatchTable")
7e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar    end = data.index("\n};\n", start)
8e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar    lines = data[start:end].split("\n")[1:]
9e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar
10e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar    # Parse the instructions.
11e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar    insns = []
12e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar    for ln in lines:
13e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar        ln = ln.split("{", 1)[1]
14e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar        ln = ln.rsplit("}", 1)[0]
15e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar        a,bc = ln.split("{", 1)
16e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar        b,c = bc.split("}", 1)
17e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar        code, string, converter, _ = [s.strip()
18e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar                                      for s in a.split(",")]
19e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar        items = [s.strip() for s in b.split(",")]
20e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar        _,features = [s.strip() for s in c.split(",")]
21e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar        assert string[0] == string[-1] == '"'
22e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar        string = string[1:-1]
23e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar        insns.append((code,string,converter,items,features))
24e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar
25e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar    # For every mnemonic, compute whether or not it can have a carry setting
26e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar    # operand and whether or not it can have a predication code.
27e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar    mnemonic_flags = {}
28e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar    for insn in insns:
29e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar        mnemonic = insn[1]
30e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar        items = insn[3]
31e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar        flags = mnemonic_flags[mnemonic] = mnemonic_flags.get(mnemonic, set())
32e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar        flags.update(items)
33e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar
34e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar    mnemonics = set(mnemonic_flags)
35e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar    ccout_mnemonics = set(m for m in mnemonics
36e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar                          if 'MCK_CCOut' in mnemonic_flags[m])
37e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar    condcode_mnemonics = set(m for m in mnemonics
38e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar                             if 'MCK_CondCode' in mnemonic_flags[m])
39e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar    noncondcode_mnemonics = mnemonics - condcode_mnemonics
40e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar    print ' || '.join('Mnemonic == "%s"' % m
41e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar                      for m in ccout_mnemonics)
42e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar    print ' || '.join('Mnemonic == "%s"' % m
43e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar                      for m in noncondcode_mnemonics)
44e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar
45e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbardef main():
46e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar    import sys
47e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar    if len(sys.argv) == 1:
48e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar        import os
49e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar        from lit.Util import capture
50e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar        llvm_obj_root = capture(["llvm-config", "--obj-root"])
51e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar        file = os.path.join(llvm_obj_root,
52e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar                            "lib/Target/ARM/ARMGenAsmMatcher.inc")
53e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar    elif len(sys.argv) == 2:
54e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar        file = sys.argv[1]
55e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar    else:
56e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar        raise NotImplementedError
57e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar
58e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar    analyze_match_table(file)
59e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar
60e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbarif __name__ == '__main__':
61e6e5fbb671c2539f4f82c6eaca51fbf400133482Daniel Dunbar    main()
62