#!/usr/bin/python # # Copyright (C) 2023 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Generate LIR files out of the definition file. * Operand usage Register allocator needs operand usage to learn which operands can share the same register. To understand register sharing options, register allocator assumes insn works in these steps: - read input operands - do the job - write output operands So, input-output operands should have dedicated registers, while input-only operands can share registers with output-only operands. There might be an exception when output-only operand is written before all input-only operands are read, so its register can't be shared. Such operands are usually referred as output-only-early-clobber operands. For register sharing, output-only-early-clobber operand is the same as input-output operand, but it is unnatural to describe output-only as input-output, so we use a special keyword for it. Finally, keywords are: use - input-only def - output-only def_early_clobber - output-only-early-clobber use_def - input-output * Scratch operands Scratch operands are actually output operands - indeed, their original value is not used and they get some new value after the insn is done. However, they are usually written before all input operands are read, so it makes sense to describe scratch operands as output-only-early-clobber. """ import gen_lir_lib import sys def main(argv): # Usage: # gen_lir.py --headers # # # # # ... # # ... # # ... # gen_lir.py --sources # # # ... # # ... # # ... mode = argv[1] lir_def_files_begin = 6 if mode == '--headers' else 4 lir_def_files_end = lir_def_files_begin while argv[lir_def_files_end].endswith('lir_instructions.json'): lir_def_files_end += 1 arch_def_files_end = lir_def_files_end while argv[arch_def_files_end].endswith('machine_ir_intrinsic_binding.json'): arch_def_files_end += 1 if mode == '--headers': arch, insns = gen_lir_lib.load_all_lir_defs( argv[lir_def_files_begin:lir_def_files_end], argv[lir_def_files_end:arch_def_files_end], argv[arch_def_files_end:]) gen_lir_lib.gen_code_2_cc(argv[2], arch, insns) gen_lir_lib.gen_machine_info_h(argv[3], arch, insns) gen_lir_lib.gen_machine_opcode_h(argv[4], arch, insns) gen_lir_lib.gen_machine_ir_h(argv[5], arch, insns) elif mode == '--sources': arch, insns = gen_lir_lib.load_all_lir_defs( argv[lir_def_files_begin:lir_def_files_end], argv[lir_def_files_end:arch_def_files_end], argv[arch_def_files_end:]) gen_lir_lib.gen_code_emit_cc(argv[2], arch, insns) gen_lir_lib.gen_code_debug_cc(argv[3], arch, insns) else: assert False, 'unknown option %s' % (mode) return 0 if __name__ == '__main__': sys.exit(main(sys.argv))