• 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
72    bool InlineCacheEnabled() override
73    {
74        return false;
75    }
76
77    ICSlot GetIcSlot() override
78    {
79        return 0;
80    }
81
82    bool oneByteSlotOnly() override
83    {
84        return false;
85    }
86
87    uint8_t IcSlots() override
88    {
89        return 0;
90    }
91
92private:
93    std::string id_;
94};
95
96% def insn2node(insn)
97%   mnemonic = insn.mnemonic.split('.')
98%   return mnemonic.map{|el| el == '64' ? 'Wide' : el.capitalize}.join()
99% end
100%
101% def is_Range(insn)
102%   if insn.mnemonic == "callrange" or insn.mnemonic == "wide.callrange" or
103%       insn.mnemonic == "callthisrange" or insn.mnemonic == "wide.callthisrange" or
104%       insn.mnemonic == "newobjrange" or insn.mnemonic == "wide.newobjrange" or
105%       insn.mnemonic == "createobjectwithexcludedkeys" or insn.mnemonic == "wide.createobjectwithexcludedkeys" or
106%       insn.mnemonic == "supercallthisrange" or insn.mnemonic == "wide.supercallthisrange" or
107%       insn.mnemonic == "supercallarrowrange" or insn.mnemonic == "wide.supercallarrowrange"
108%      return true
109%   end
110%   return false
111% end
112%
113% def is_VReg(name)
114%     if name ==  :v
115%        return true
116%     end
117% end
118%
119% def is_Acc(name)
120%    if name ==  :acc
121%        return true
122%     end
123% end
124%
125% def is_Imm(name)
126%    if name ==  :imm
127%        return true
128%     end
129% end
130%
131% def is_Id(name)
132%     if %i[method_id type_id field_id string_id stringId callsite_id literalarray_id].include?(name)
133%        return true
134%     end
135% end
136%
137% def get_operand_type(name, name_tmp, insn, map)
138%   if is_VReg (name_tmp)
139%     map['reg'].push("#{name}_")
140%     return 'VReg'
141%   elsif is_Imm(name_tmp)
142%     if insn.properties.include? 'jump'
143%       map['lbl'].push("#{name}_")
144%       return "Label*"
145%     end
146%     map['imm'].push("#{name}_")
147%     if insn.sig.include? 'imm:f64'
148%       return 'double'
149%     end
150%       return 'int64_t'
151%   elsif is_Id(name_tmp)
152%     map['str'].push("#{name}_")
153%     return 'util::StringView'
154%   else
155%     return nil
156%   end
157% end
158%
159% def get_operands(sig)
160%     return [] unless sig.include? ' '
161%     _, operands = sig.match(/(\S+) (.+)/).captures
162%     operands = operands.split(', ')
163%     end
164%
165% def get_ctor_args(insn)
166%     operands = get_operands(insn.sig)
167%     ops = Array.new
168%     ctor_args = Array.new
169%     op_map = Hash.new { |h, k| h[k] = [] }
170%     id_count = 0
171%     operands.map do |operand|
172%     operand_parts = operand.split(':')
173%       case operand_parts.size
174%       when 1
175%         name = operand_parts[0]
176%       when 2
177%         name, _ = operand_parts
178%       when 3
179%         name, _, _ = operand_parts
180%       else
181%         raise 'Unexpected operand string'
182%       end
183%
184%       name_tmp = name_tmp = name.to_s.gsub(/[0-9]/, '').to_sym;
185%
186%       if is_Id(name_tmp)
187%           name = "stringId_"
188%           name.concat(id_count.to_s)
189%           id_count = id_count + 1
190%       end
191%
192%       ops.push(name)
193%       type = get_operand_type(name, name_tmp, insn, op_map)
194%       ctor_args.push("#{type} #{name}")
195%     end
196%     return ops,ctor_args,op_map
197% end
198%
199% Panda::instructions.group_by(&:mnemonic).each do |mnemonic, group|
200% insn = group.first
201% node_kind = get_node_kind(mnemonic)
202% class_name = insn2node(insn)
203% is_range_op = is_Range(insn)
204% base_class = "IRNode"
205% ops_list,ctor_arg_list,op_map = get_ctor_args(insn)
206% ctor_args = "const ir::AstNode* node" + (ctor_arg_list.length == 0 ? "" : ", ") + ctor_arg_list.map {|arg| "#{arg}"}.join(", ")
207% members = ctor_arg_list.map {|arg| "#{arg}_;"}.join("\n    ")
208% registers = op_map['reg'].map {|reg| "&#{reg}"}.join(", ")
209% ops = (ops_list.length == 0 ? "" : ", ") + ops_list.map { |op| "#{op}_(#{op})"}.join(", ")
210class <%= class_name %> : public <%= base_class %>
211{
212public:
213    explicit <%= class_name %>(<%= ctor_args %>) : <%= base_class %>(node)<%= ops %> {}
214
215    Formats GetFormats() const override {
216        return Span<const Format>(<%= get_format_name(insn.mnemonic) %>);
217    }
218
219    size_t Registers([[maybe_unused]] std::array<VReg*, MAX_REG_OPERAND>* regs) override
220    {
221% reg_cnt = 0
222% for reg in op_map['reg']
223        (*regs)[<%= reg_cnt %>] = &<%= reg %>;
224%   reg_cnt+=1;
225% end
226        return <%= reg_cnt %>;
227    }
228
229    size_t Registers([[maybe_unused]] std::array<const VReg*, MAX_REG_OPERAND>* regs) const override
230    {
231% reg_cnt = 0
232% for reg in op_map['reg']
233        (*regs)[<%= reg_cnt %>] = &<%= reg %>;
234%   reg_cnt+=1;
235% end
236        return <%= reg_cnt %>;
237    }
238
239    void Transform(pandasm::Ins* ins) const override
240    {
241        ins->opcode = pandasm::Opcode::<%= node_kind %>;
242% if op_map['reg'].length != 0
243        ins->regs.reserve(<%= op_map['reg'].length %>);
244% end
245% if op_map['imm'].length != 0
246        ins->imms.reserve(<%= op_map['imm'].length %>);
247% end
248% if op_map['str'].length + op_map['lbl'].length != 0
249        ins->ids.reserve(<%= op_map['str'].length + op_map['lbl'].length %>);
250% end
251% for reg in op_map['reg']
252        ins->regs.emplace_back(<%= reg %>);
253% end
254% for imm in op_map['imm']
255        ins->imms.emplace_back(<%= imm %>);
256% end
257% for str in op_map['str']
258        ins->ids.emplace_back(<%= str %>.Mutf8());
259% end
260% for lbl in op_map['lbl']
261        ins->ids.emplace_back(<%= lbl %>->Id());
262% end
263    }
264
265    ICSlot SetIcSlot(IcSizeType slot) override
266    {
267% is_jit_ic = insn.properties.include?("jit_ic_slot")
268% is_ic = (!is_jit_ic) && insn.properties.include?("ic_slot")
269% if (!is_jit_ic && !is_ic)
270        return 0;
271% else
272%   ret = insn.properties.include?("one_slot") ? 1 : 2;
273        constexpr static ICSlot invalid = 0xFF;
274%   if (is_ic)
275        if (slot <= 0xFF) {
276            if ((slot + <%= ret %>) > 0xFF) {
277                <%= op_map['imm'][0] %> = 0x100;
278                return <%= ret %> + (0x100 - slot);
279            }
280
281            <%= op_map['imm'][0] %> = slot;
282            return <%= ret %>;
283        }
284
285        if (slot > 0xFF && slot <= 0xFFFF) {
286            <%= op_map['imm'][0] %> = slot;
287            return <%= ret %>;
288        }
289
290        <%= op_map['imm'][0] %> = invalid;
291        return 0;
292%   end
293%   if (is_jit_ic && !is_ic)
294        if (slot < 0xFF) {
295            if ((slot + <%= ret %>) > 0xFF) {
296                <%= op_map['imm'][0] %> = invalid;
297                return 0;
298            }
299
300            <%= op_map['imm'][0] %> = slot;
301            return <%= ret %>;
302        }
303
304        <%= op_map['imm'][0] %> = invalid;
305        return 0;
306%   end
307% end
308    }
309
310    bool InlineCacheEnabled() override
311    {
312% is_jit_ic = insn.properties.include?("jit_ic_slot")
313% is_ic = (!is_jit_ic) && insn.properties.include?("ic_slot")
314% if (!is_jit_ic && !is_ic)
315        return false;
316% else
317        return true;
318% end
319    }
320
321    ICSlot GetIcSlot() override
322    {
323% is_jit_ic = insn.properties.include?("jit_ic_slot")
324% is_ic = (!is_jit_ic) && insn.properties.include?("ic_slot")
325% if (!is_jit_ic && !is_ic)
326        return 0;
327% else
328        return <%= op_map['imm'][0] %>;
329% end
330    }
331
332    bool oneByteSlotOnly() override
333    {
334% is_jit_ic = insn.properties.include?("jit_ic_slot")
335% if (is_jit_ic)
336        return true;
337% else
338        return false;
339% end
340    }
341
342    uint8_t IcSlots() override
343    {
344% is_jit_ic = insn.properties.include?("jit_ic_slot")
345% is_ic = (!is_jit_ic) && insn.properties.include?("ic_slot")
346% if (!is_jit_ic && !is_ic)
347        return 0;
348% else
349%   ret = insn.properties.include?("one_slot") ? 1 : 2;
350        return <%= ret %>;
351% end
352    }
353
354% if is_range_op
355    bool IsRangeInst() const override
356    {
357        return true;
358    }
359
360    int64_t RangeRegsCount() override
361    {
362%   if insn.mnemonic == "createobjectwithexcludedkeys" or insn.mnemonic.start_with? "wide."
363%       if insn.mnemonic == "wide.callthisrange" or insn.mnemonic == "createobjectwithexcludedkeys" or
364%           insn.mnemonic == "wide.createobjectwithexcludedkeys"
365        return <%= op_map['imm'][0] %> + 1;
366%       else
367        return <%= op_map['imm'][0] %>;
368%       end
369%   else
370%       if insn.mnemonic == "callthisrange"
371        return <%= op_map['imm'][1] %> + 1;
372%       else
373        return <%= op_map['imm'][1] %>;
374%       end
375%   end
376    }
377% end
378
379% if ops_list.length != 0
380private:
381    <%= members %>
382% end
383};
384
385% end
386}  // namespace panda::es2panda::compiler
387
388#endif
389