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