• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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