• 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% is_8_bit_ic = insn.properties.include?("eight_bit_ic")
270% is_16_bit_ic = (!is_8_bit_ic) && insn.properties.include?("sixteen_bit_ic")
271% is_8_16_bit_ic = (!is_16_bit_ic) && insn.properties.include?("eight_sixteen_bit_ic")
272% if (!is_jit_ic && !is_ic)
273        return 0;
274% else
275%   ret = insn.properties.include?("one_slot") ? 1 : 2;
276        constexpr static ICSlot invalid = 0xFF;
277%   if (is_16_bit_ic || is_8_16_bit_ic)
278        if (slot <= 0xFF) {
279            if ((slot + <%= ret %>) > 0xFF) {
280                <%= op_map['imm'][0] %> = 0x100;
281                return <%= ret %> + (0x100 - slot);
282            }
283
284            <%= op_map['imm'][0] %> = slot;
285            return <%= ret %>;
286        }
287
288        if (slot > 0xFF && slot <= 0xFFFF) {
289            <%= op_map['imm'][0] %> = slot;
290            return <%= ret %>;
291        }
292
293        <%= op_map['imm'][0] %> = invalid;
294        return 0;
295%   end
296%   if (is_8_bit_ic)
297        if (slot <= 0xFF) {
298            if ((slot + <%= ret %>) > 0xFF) {
299                <%= op_map['imm'][0] %> = invalid;
300                return 0x100 - slot;
301            }
302
303            <%= op_map['imm'][0] %> = slot;
304            return <%= ret %>;
305        }
306
307        <%= op_map['imm'][0] %> = invalid;
308        return 0;
309%   end
310% end
311    }
312
313    bool InlineCacheEnabled() 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 false;
319% else
320        return true;
321% end
322    }
323
324    ICSlot GetIcSlot() 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 0;
330% else
331        return <%= op_map['imm'][0] %>;
332% end
333    }
334
335    bool oneByteSlotOnly() override
336    {
337% is_jit_ic = insn.properties.include?("jit_ic_slot")
338% is_ic = (!is_jit_ic) && insn.properties.include?("ic_slot")
339% if (!is_jit_ic && !is_ic)
340        return false;
341% end
342% is_8_bit_ic = insn.properties.include?("eight_bit_ic")
343% if (is_8_bit_ic)
344        return true;
345% else
346        return false;
347% end
348    }
349
350    uint8_t IcSlots() override
351    {
352% is_jit_ic = insn.properties.include?("jit_ic_slot")
353% is_ic = (!is_jit_ic) && insn.properties.include?("ic_slot")
354% if (!is_jit_ic && !is_ic)
355        return 0;
356% else
357%   ret = insn.properties.include?("one_slot") ? 1 : 2;
358        return <%= ret %>;
359% end
360    }
361
362% if is_range_op
363    bool IsRangeInst() const override
364    {
365        return true;
366    }
367
368    int64_t RangeRegsCount() override
369    {
370%   if insn.mnemonic == "createobjectwithexcludedkeys" or insn.mnemonic.start_with? "wide."
371%       if insn.mnemonic == "wide.callthisrange" or insn.mnemonic == "createobjectwithexcludedkeys" or
372%           insn.mnemonic == "wide.createobjectwithexcludedkeys"
373        return <%= op_map['imm'][0] %> + 1;
374%       else
375        return <%= op_map['imm'][0] %>;
376%       end
377%   else
378%       if insn.mnemonic == "callthisrange"
379        return <%= op_map['imm'][1] %> + 1;
380%       else
381        return <%= op_map['imm'][1] %>;
382%       end
383%   end
384    }
385% end
386
387% if ops_list.length != 0
388private:
389    <%= members %>
390% end
391};
392
393% end
394}  // namespace panda::es2panda::compiler
395
396#endif
397