| #!/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 <insn-inl.h> | 
 |   #                        <machine_info-inl.h> | 
 |   #                        <machine_opcode-inl.h> | 
 |   #                        <machine_ir-inl.h> | 
 |   #                        <lir_instructions.json> | 
 |   #                        ... | 
 |   #                        <machine_ir_intrinsic_binding.json> | 
 |   #                        ... | 
 |   #                        <def> | 
 |   #                        ... | 
 |   #   gen_lir.py --sources <code_emit.cc> | 
 |   #                        <code_debug.cc> | 
 |   #                        <lir_instructions.json> | 
 |   #                        ... | 
 |   #                        <machine_ir_intrinsic_binding.json> | 
 |   #                        ... | 
 |   #                        <def> | 
 |   #                        ... | 
 |  | 
 |   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)) |