• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/python
2#
3# Copyright (C) 2023 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#      http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17
18import json
19import re
20import sys
21
22# Add numbers to the names of fields to rearrange them better.
23# They would be removed from final file.
24field_substitute = {
25  'name' : '|000|name',
26  'encodings' : '|000|encodings',
27  'stems' : '|000|stems',
28  'feature' : '|001|feature',
29  'args' : '|010|args',
30  'comment' : '|015|comment',
31  'asm' : '|020|asm',
32  'opcodes' : '|021|opcodes',
33  'reg_to_rm' : '|022|reg_to_rm',
34  'mnemo' : '|030|mnemo',
35}
36
37def Version(str):
38  result = []
39  isdigit = False
40  word = ''
41  for char in str + ('a' if str[-1:].isdigit() else '0'):
42    if char.isdigit() == isdigit:
43      word += char
44    else:
45      if isdigit:
46        result.append(('0' * 1000 + word)[-1000:])
47      else:
48        result.append((word + ' ' * 1000)[:1000])
49      isdigit = not isdigit
50      word = char
51  return '.'.join(result)
52
53def main(argv):
54  # Usage: prettify_asm_def.py <file.json>
55
56  with open(argv[1]) as file:
57    obj = json.load(file)
58
59  insns = {}
60  for insn in obj['insns']:
61    if 'stems' in insn:
62      sorted_stems = sorted(insn['stems'])
63      insn['stems'] = sorted_stems
64      name = Version(', '.join(sorted_stems) + '; ' + str(insn['args']))
65    elif 'encodings' in insn:
66      sorted_stems = sorted(insn['encodings'])
67      name = Version(', '.join(sorted_stems) + '; ' + str(insn['args']))
68    else:
69      name = Version(insn['name'] + '; ' + str(insn['args']))
70    new_insn = {}
71    for field, value in insn.items():
72      new_insn[field_substitute[field]] = value
73    assert name not in insns
74    insns[name] = new_insn
75
76  obj['insns'] = [insn[1] for insn in sorted(iter(insns.items()))]
77
78  text = json.dumps(obj, indent=2, sort_keys=True)
79
80  # Remove numbers from names of fields
81  text = re.sub('[|][0-9][0-9][0-9][|]', '', text)
82
83  def replace_if_short(match):
84    match = match.group()
85    replace = ' '.join(match.split())
86    if len(replace) < 100 or (
87       len(replace) < 120 and 'optimizable_using_commutation' in replace):
88      return replace
89    else:
90      return match
91
92  # Make short lists one-liners
93  text = re.sub('[\[{][^][{}]*[]}]', replace_if_short, text)
94  # Allow opcodes list.
95  text = re.sub('[\[{][^][{}]*"opcodes"[^][{}]*[\[{][^][{}]*[]}][^][{}]*[]}]', replace_if_short, text)
96
97  # Remove trailing spaces
98  text = re.sub(' $', '', text, flags=re.MULTILINE)
99
100  # Fix the license
101  text = re.sub('\\\\u201c', '“', text, flags=re.MULTILINE)
102  text = re.sub('\\\\u201d', '”', text, flags=re.MULTILINE)
103
104  with open(argv[1], 'w') as file:
105    print(text, file=file)
106
107if __name__ == '__main__':
108  sys.exit(main(sys.argv))
109