• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1% def get_node_kind(mnemonic)
2%   return "#{mnemonic.gsub('.', '_').upcase}"
3% end
4%
5% def get_format_name(mnemonic)
6%   return "#{mnemonic.gsub('.', '_').upcase}" + "_FORMATS"
7% end
8/**
9 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
21 */
22
23// Autogenerated file -- DO NOT EDIT!
24
25#ifndef ES2PANDA_COMPILER_GEN_IR_ISA_H
26#define ES2PANDA_COMPILER_GEN_IR_ISA_H
27
28#include <ir/irnode.h>
29#include <gen/formats.h>
30#include <assembly-ins.h>
31
32namespace panda::es2panda::compiler {
33
34class Label : public IRNode {
35public:
36    explicit Label(const ir::AstNode* node, std::string id) : IRNode(node), id_(std::move(id)) {}
37
38    static constexpr std::string_view PREFIX = "LABEL_";
39
40    Formats GetFormats() const override
41    {
42        return Span<const Format>(nullptr, nullptr);
43    }
44
45    const std::string &Id() const
46    {
47        return id_;
48    }
49
50    size_t Registers([[maybe_unused]] std::array<VReg*, MAX_REG_OPERAND>* regs) override
51    {
52        return 0;
53    }
54
55    size_t Registers([[maybe_unused]] std::array<const VReg*, MAX_REG_OPERAND>* regs) const override
56    {
57        return 0;
58    }
59
60    void Transform(pandasm::Ins *ins) const override
61    {
62        ins->opcode = pandasm::Opcode::INVALID;
63        ins->set_label = true;
64        ins->label = id_;
65    }
66
67    ICSlot SetIcSlot(IcSizeType currentSlot) override
68    {
69        return 0;
70    }
71
72private:
73    std::string id_;
74};
75
76% def insn2node(insn)
77%   mnemonic = insn.mnemonic.split('.')
78%   return mnemonic.map{|el| el == '64' ? 'Wide' : el.capitalize}.join()
79% end
80%
81% def is_Range(insn)
82%   if insn.mnemonic == "callrange" or insn.mnemonic == "wide.callrange" or
83%       insn.mnemonic == "callthisrange" or insn.mnemonic == "wide.callthisrange" or
84%       insn.mnemonic == "newobjrange" or insn.mnemonic == "wide.newobjrange" or
85%       insn.mnemonic == "createobjectwithexcludedkeys" or insn.mnemonic == "wide.createobjectwithexcludedkeys" or
86%       insn.mnemonic == "supercallthisrange" or insn.mnemonic == "wide.supercallthisrange" or
87%       insn.mnemonic == "supercallarrowrange" or insn.mnemonic == "wide.supercallarrowrange"
88%      return true
89%   end
90%   return false
91% end
92%
93% def is_VReg(name)
94%     if name ==  :v
95%        return true
96%     end
97% end
98%
99% def is_Acc(name)
100%    if name ==  :acc
101%        return true
102%     end
103% end
104%
105% def is_Imm(name)
106%    if name ==  :imm
107%        return true
108%     end
109% end
110%
111% def is_Id(name)
112%     if %i[method_id type_id field_id string_id stringId callsite_id literalarray_id].include?(name)
113%        return true
114%     end
115% end
116%
117% def get_operand_type(name, name_tmp, insn, map)
118%   if is_VReg (name_tmp)
119%     map['reg'].push("#{name}_")
120%     return 'VReg'
121%   elsif is_Imm(name_tmp)
122%     if insn.properties.include? 'jump'
123%       map['lbl'].push("#{name}_")
124%       return "Label*"
125%     end
126%     map['imm'].push("#{name}_")
127%     if insn.sig.include? 'imm:f64'
128%       return 'double'
129%     end
130%       return 'int64_t'
131%   elsif is_Id(name_tmp)
132%     map['str'].push("#{name}_")
133%     return 'util::StringView'
134%   else
135%     return nil
136%   end
137% end
138%
139% def get_operands(sig)
140%     return [] unless sig.include? ' '
141%     _, operands = sig.match(/(\S+) (.+)/).captures
142%     operands = operands.split(', ')
143%     end
144%
145% def get_ctor_args(insn)
146%     operands = get_operands(insn.sig)
147%     ops = Array.new
148%     ctor_args = Array.new
149%     op_map = Hash.new { |h, k| h[k] = [] }
150%     id_count = 0
151%     operands.map do |operand|
152%     operand_parts = operand.split(':')
153%       case operand_parts.size
154%       when 1
155%         name = operand_parts[0]
156%       when 2
157%         name, _ = operand_parts
158%       when 3
159%         name, _, _ = operand_parts
160%       else
161%         raise 'Unexpected operand string'
162%       end
163%
164%       name_tmp = name_tmp = name.to_s.gsub(/[0-9]/, '').to_sym;
165%
166%       if is_Id(name_tmp)
167%           name = "stringId_"
168%           name.concat(id_count.to_s)
169%           id_count = id_count + 1
170%       end
171%
172%       ops.push(name)
173%       type = get_operand_type(name, name_tmp, insn, op_map)
174%       ctor_args.push("#{type} #{name}")
175%     end
176%     return ops,ctor_args,op_map
177% end
178%
179% Panda::instructions.group_by(&:mnemonic).each do |mnemonic, group|
180% insn = group.first
181% node_kind = get_node_kind(mnemonic)
182% class_name = insn2node(insn)
183% is_range_op = is_Range(insn)
184% base_class = "IRNode"
185% ops_list,ctor_arg_list,op_map = get_ctor_args(insn)
186% ctor_args = "const ir::AstNode* node" + (ctor_arg_list.length == 0 ? "" : ", ") + ctor_arg_list.map {|arg| "#{arg}"}.join(", ")
187% members = ctor_arg_list.map {|arg| "#{arg}_;"}.join("\n    ")
188% registers = op_map['reg'].map {|reg| "&#{reg}"}.join(", ")
189% ops = (ops_list.length == 0 ? "" : ", ") + ops_list.map { |op| "#{op}_(#{op})"}.join(", ")
190class <%= class_name %> : public <%= base_class %>
191{
192public:
193    explicit <%= class_name %>(<%= ctor_args %>) : <%= base_class %>(node)<%= ops %> {}
194
195    Formats GetFormats() const override {
196        return Span<const Format>(<%= get_format_name(insn.mnemonic) %>);
197    }
198
199    size_t Registers([[maybe_unused]] std::array<VReg*, MAX_REG_OPERAND>* regs) override
200    {
201% reg_cnt = 0
202% for reg in op_map['reg']
203        (*regs)[<%= reg_cnt %>] = &<%= reg %>;
204%   reg_cnt+=1;
205% end
206        return <%= reg_cnt %>;
207    }
208
209    size_t Registers([[maybe_unused]] std::array<const VReg*, MAX_REG_OPERAND>* regs) const override
210    {
211% reg_cnt = 0
212% for reg in op_map['reg']
213        (*regs)[<%= reg_cnt %>] = &<%= reg %>;
214%   reg_cnt+=1;
215% end
216        return <%= reg_cnt %>;
217    }
218
219    void Transform(pandasm::Ins* ins) const override
220    {
221        ins->opcode = pandasm::Opcode::<%= node_kind %>;
222% if op_map['reg'].length != 0
223        ins->regs.reserve(<%= op_map['reg'].length %>);
224% end
225% if op_map['imm'].length != 0
226        ins->imms.reserve(<%= op_map['imm'].length %>);
227% end
228% if op_map['str'].length + op_map['lbl'].length != 0
229        ins->ids.reserve(<%= op_map['str'].length + op_map['lbl'].length %>);
230% end
231% for reg in op_map['reg']
232        ins->regs.emplace_back(<%= reg %>);
233% end
234% for imm in op_map['imm']
235        ins->imms.emplace_back(<%= imm %>);
236% end
237% for str in op_map['str']
238        ins->ids.emplace_back(<%= str %>.Mutf8());
239% end
240% for lbl in op_map['lbl']
241        ins->ids.emplace_back(<%= lbl %>->Id());
242% end
243    }
244
245    ICSlot SetIcSlot(IcSizeType slot) override
246    {
247% is_jit_ic = insn.properties.include?("jit_ic_slot")
248% is_ic = (!is_jit_ic) && insn.properties.include?("ic_slot")
249% if (!is_jit_ic && !is_ic)
250        return 0;
251% else
252%   ret = insn.properties.include?("one_slot") ? 1 : 2;
253        constexpr static ICSlot invalid = 0xFF;
254%   if (is_ic)
255        if (slot <= 0xFF) {
256            if ((slot + <%= ret %>) > 0xFF) {
257                <%= op_map['imm'][0] %> = 0x100;
258                return <%= ret %> + (0x100 - slot);
259            }
260
261            <%= op_map['imm'][0] %> = slot;
262            return <%= ret %>;
263        }
264
265        if (slot > 0xFF && slot <= 0xFFFF) {
266            <%= op_map['imm'][0] %> = slot;
267            return <%= ret %>;
268        }
269
270        <%= op_map['imm'][0] %> = invalid;
271        return 0;
272%   end
273%   if (is_jit_ic && !is_ic)
274        if (slot < 0xFF) {
275            if ((slot + <%= ret %>) > 0xFF) {
276                <%= op_map['imm'][0] %> = invalid;
277                return 0;
278            }
279
280            <%= op_map['imm'][0] %> = slot;
281            return <%= ret %>;
282        }
283
284        <%= op_map['imm'][0] %> = invalid;
285        return 0;
286%   end
287% end
288    }
289
290% if is_range_op
291    bool IsRangeInst() const override
292    {
293        return true;
294    }
295
296    int64_t RangeRegsCount() override
297    {
298%   if insn.mnemonic == "createobjectwithexcludedkeys" or insn.mnemonic.start_with? "wide."
299%       if insn.mnemonic == "wide.callthisrange" or insn.mnemonic == "createobjectwithexcludedkeys" or
300%           insn.mnemonic == "wide.createobjectwithexcludedkeys"
301        return <%= op_map['imm'][0] %> + 1;
302%       else
303        return <%= op_map['imm'][0] %>;
304%       end
305%   else
306%       if insn.mnemonic == "callthisrange"
307        return <%= op_map['imm'][1] %> + 1;
308%       else
309        return <%= op_map['imm'][1] %>;
310%       end
311%   end
312    }
313% end
314
315% if ops_list.length != 0
316private:
317    <%= members %>
318% end
319};
320
321% end
322}  // namespace panda::es2panda::compiler
323
324#endif
325