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"""Generate LIR files out of the definition file. 18 19* Operand usage 20 21Register allocator needs operand usage to learn which operands can share the 22same register. 23 24To understand register sharing options, register allocator assumes insn works 25in these steps: 26- read input operands 27- do the job 28- write output operands 29 30So, input-output operands should have dedicated registers, while input-only 31operands can share registers with output-only operands. 32 33There might be an exception when output-only operand is written before all 34input-only operands are read, so its register can't be shared. Such operands 35are usually referred as output-only-early-clobber operands. 36 37For register sharing, output-only-early-clobber operand is the same as 38input-output operand, but it is unnatural to describe output-only as 39input-output, so we use a special keyword for it. 40 41Finally, keywords are: 42use - input-only 43def - output-only 44def_early_clobber - output-only-early-clobber 45use_def - input-output 46 47* Scratch operands 48 49Scratch operands are actually output operands - indeed, their original value 50is not used and they get some new value after the insn is done. However, they 51are usually written before all input operands are read, so it makes sense to 52describe scratch operands as output-only-early-clobber. 53""" 54 55import gen_lir_lib 56import sys 57 58def main(argv): 59 # Usage: 60 # gen_lir.py --headers <insn-inl.h> 61 # <machine_info-inl.h> 62 # <machine_opcode-inl.h> 63 # <machine_ir-inl.h> 64 # <lir_instructions.json> 65 # ... 66 # <machine_ir_intrinsic_binding.json> 67 # ... 68 # <def> 69 # ... 70 # gen_lir.py --sources <code_emit.cc> 71 # <code_debug.cc> 72 # <lir_instructions.json> 73 # ... 74 # <machine_ir_intrinsic_binding.json> 75 # ... 76 # <def> 77 # ... 78 79 mode = argv[1] 80 lir_def_files_begin = 6 if mode == '--headers' else 4 81 lir_def_files_end = lir_def_files_begin 82 while argv[lir_def_files_end].endswith('lir_instructions.json'): 83 lir_def_files_end += 1 84 arch_def_files_end = lir_def_files_end 85 while argv[arch_def_files_end].endswith('machine_ir_intrinsic_binding.json'): 86 arch_def_files_end += 1 87 88 if mode == '--headers': 89 arch, insns = gen_lir_lib.load_all_lir_defs( 90 argv[lir_def_files_begin:lir_def_files_end], 91 argv[lir_def_files_end:arch_def_files_end], 92 argv[arch_def_files_end:]) 93 gen_lir_lib.gen_code_2_cc(argv[2], arch, insns) 94 gen_lir_lib.gen_machine_info_h(argv[3], arch, insns) 95 gen_lir_lib.gen_machine_opcode_h(argv[4], arch, insns) 96 gen_lir_lib.gen_machine_ir_h(argv[5], arch, insns) 97 elif mode == '--sources': 98 arch, insns = gen_lir_lib.load_all_lir_defs( 99 argv[lir_def_files_begin:lir_def_files_end], 100 argv[lir_def_files_end:arch_def_files_end], 101 argv[arch_def_files_end:]) 102 gen_lir_lib.gen_code_emit_cc(argv[2], arch, insns) 103 gen_lir_lib.gen_code_debug_cc(argv[3], arch, insns) 104 else: 105 assert False, 'unknown option %s' % (mode) 106 107 return 0 108 109 110if __name__ == '__main__': 111 sys.exit(main(sys.argv)) 112