1#!/usr/bin/env ruby 2# Copyright (c) 2021-2024 Huawei Device Co., Ltd. 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15require 'erb' 16require 'creator' 17require 'calculator' 18 19module GeneratorTags 20 ACC_NUM = 65_536 21 22 class InstructionBuild 23 def initialize(instr, create) 24 @instr = instr 25 @create = create 26 end 27 28 def bind 29 binding 30 end 31 end 32 33 class Generator 34 INT_VAL = 42 35 FLOAT_VAL = 42.42 36 37 def generate_input_number(type, in_reg_num) 38 val = 0 39 case type[0] 40 when 'b' 41 val = INT_VAL 42 when 'i' 43 val = INT_VAL 44 when 'f' 45 val = FLOAT_VAL 46 when 'u' 47 val = in_reg_num 48 end 49 val 50 end 51 52 def initialize(template) 53 @template = template 54 @command = {} 55 @creator = Creator.new 56 @calculator = Calculator.new 57 end 58 59 def skip?(inst) 60 !inst.dst? || inst.dyn? || !inst.core? 61 end 62 63 def concat_args(instr, create) 64 command = instr.mnemonic 65 if create['ctor'] 66 command += " #{@command['ctor']}" 67 command += ',' if instr.src? || @command['out_reg'] 68 end 69 if @command['method_id'] 70 command += " #{@command['method_id']}" 71 command += ',' if instr.src? || @command['out_reg'] 72 end 73 if @command['out_reg'] 74 command += " #{@command['out_reg']}" 75 command += ', ' if instr.reg_src? || @command['literalarray_id'] || @command['field_id'] 76 end 77 iops = instr.in_ops 78 79 iops[0].insert = 'v4' if create['virt'] 80 81 iops.each do |op| 82 next if op.insert == '' 83 84 command += " #{op.insert}" 85 command += ', ' if iops.size != 1 && op != iops[-1] || @command['field_id'] 86 end 87 if @command['type_id'] 88 command += ',' if @command['out_reg'] || !iops.empty? 89 command += " #{@command['type_id']}" 90 end 91 command += " #{@command['string_id']}" if @command['string_id'] 92 command += " #{@command['field_id']}" if @command['field_id'] 93 command += " #{@command['literalarray_id']}" if @command['literalarray_id'] 94 command 95 end 96 97 def generate_file(new_file, instr) 98 @calculator.refresh 99 @command['fill_reg'] = [] 100 iops = instr.in_ops 101 iops.each do |op| 102 if op.imm? 103 op.insert = generate_input_number(op.type, iops.size - 1) 104 elsif op.reg? && op.src? && op.dst? 105 op.insert = '' 106 elsif op.type.include?('[]') # Array 107 op.insert = 'v3' 108 elsif op.type.include?('ref') # Object 109 op.insert = 'v4' 110 elsif op.reg? 111 if !(op.type.include?('top') || op.type.include?('[]')) 112 free_reg = @calculator.free_register 113 @command['fill_reg'].append(free_reg) 114 else 115 free_reg = 'v3' # top[] case 116 end 117 op.insert = free_reg 118 end 119 end 120 if instr.reg_dst? 121 @command['dst_reg'] = 0 122 @command['out_reg'] = 'v0' 123 else 124 @command['dst_reg'] = ACC_NUM 125 end 126 @command['expected_tag'] = @calculator.calculate_expected_tag(instr.dtype) 127 @command, create_list = @creator.create(instr, @command) 128 @command['sig'] = concat_args(instr, create_list) 129 @command['in_ops'] = instr.in_ops 130 templ_instr = InstructionBuild.new(@command, create_list) 131 erb = ERB.new(@template) 132 new_file << erb.result(templ_instr.bind) 133 @command.clear 134 end 135 end 136end 137