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