% def get_node_kind(mnemonic)
% return "#{mnemonic.gsub('.', '_').upcase}"
% end
%
% def get_format_name(mnemonic)
% return "#{mnemonic.gsub('.', '_').upcase}" + "_FORMATS"
% end
/**
* Copyright (c) 2021-2026 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Autogenerated file -- DO NOT EDIT!
#ifndef ES2PANDA_COMPILER_GEN_IR_ISA_H
#define ES2PANDA_COMPILER_GEN_IR_ISA_H
#include <ir/irnode.h>
#include <gen/formats.h>
#include <assembly-ins.h>
namespace panda::es2panda::compiler {
class Label : public IRNode {
public:
explicit Label(const ir::AstNode* node, std::string id) : IRNode(node), id_(std::move(id)) {}
static constexpr std::string_view PREFIX = "LABEL_";
Formats GetFormats() const override
{
return Span<const Format>(nullptr, nullptr);
}
const std::string &Id() const
{
return id_;
}
size_t Registers([[maybe_unused]] std::array<VReg*, MAX_REG_OPERAND>* regs) override
{
return 0;
}
size_t Registers([[maybe_unused]] std::array<const VReg*, MAX_REG_OPERAND>* regs) const override
{
return 0;
}
pandasm::Ins *Transform() const override
{
return new pandasm::LabelIns(id_);
}
ICSlot SetIcSlot(IcSizeType currentSlot) override
{
return 0;
}
bool InlineCacheEnabled() override
{
return false;
}
ICSlot GetIcSlot() override
{
return 0;
}
bool oneByteSlotOnly() override
{
return false;
}
uint8_t IcSlots() override
{
return 0;
}
private:
std::string id_;
};
% def insn2node(insn)
% mnemonic = insn.mnemonic.split('.')
% return mnemonic.map{|el| el == '64' ? 'Wide' : el.capitalize}.join()
% end
%
% def is_Range(insn)
% if insn.mnemonic == "callrange" or insn.mnemonic == "wide.callrange" or
% insn.mnemonic == "callthisrange" or insn.mnemonic == "wide.callthisrange" or
% insn.mnemonic == "newobjrange" or insn.mnemonic == "wide.newobjrange" or
% insn.mnemonic == "createobjectwithexcludedkeys" or insn.mnemonic == "wide.createobjectwithexcludedkeys" or
% insn.mnemonic == "supercallthisrange" or insn.mnemonic == "wide.supercallthisrange" or
% insn.mnemonic == "supercallarrowrange" or insn.mnemonic == "wide.supercallarrowrange" or
% insn.mnemonic == "callthisrangewithname" or insn.mnemonic == "wide.callthisrangewithname"
% return true
% end
% return false
% end
%
% def is_VReg(name)
% if name == :v
% return true
% end
% end
%
% def is_Acc(name)
% if name == :acc
% return true
% end
% end
%
% def is_Imm(name)
% if name == :imm
% return true
% end
% end
%
% def is_Id(name)
% if %i[method_id type_id field_id string_id stringId callsite_id literalarray_id].include?(name)
% return true
% end
% end
%
% def get_operand_type(name, name_tmp, insn, map)
% if is_VReg (name_tmp)
% map['reg'].push("#{name}_")
% return 'VReg'
% elsif is_Imm(name_tmp)
% if insn.properties.include? 'jump'
% map['lbl'].push("#{name}_")
% return "Label*"
% end
% map['imm'].push("#{name}_")
% if insn.sig.include? 'imm:f64'
% return 'double'
% end
% return 'int64_t'
% elsif is_Id(name_tmp)
% map['str'].push("#{name}_")
% return 'util::StringView'
% else
% return nil
% end
% end
%
% def get_operands(sig)
% return [] unless sig.include? ' '
% _, operands = sig.match(/(\S+) (.+)/).captures
% operands = operands.split(', ')
% end
%
% def get_ctor_args(insn)
% operands = get_operands(insn.sig)
% ops = Array.new
% ctor_args = Array.new
% op_map = Hash.new { |h, k| h[k] = [] }
% id_count = 0
% operands.map do |operand|
% operand_parts = operand.split(':')
% case operand_parts.size
% when 1
% name = operand_parts[0]
% when 2
% name, _ = operand_parts
% when 3
% name, _, _ = operand_parts
% else
% raise 'Unexpected operand string'
% end
%
% name_tmp = name_tmp = name.to_s.gsub(/[0-9]/, '').to_sym;
%
% if is_Id(name_tmp)
% name = "stringId_"
% name.concat(id_count.to_s)
% id_count = id_count + 1
% end
%
% ops.push(name)
% type = get_operand_type(name, name_tmp, insn, op_map)
% ctor_args.push("#{type} #{name}")
% end
% return ops,ctor_args,op_map
% end
%
% Panda::instructions.group_by(&:mnemonic).each do |mnemonic, group|
% insn = group.first
% node_kind = get_node_kind(mnemonic)
% class_name = insn2node(insn)
% is_range_op = is_Range(insn)
% base_class = "IRNode"
% ops_list,ctor_arg_list,op_map = get_ctor_args(insn)
% ctor_args = "const ir::AstNode* node" + (ctor_arg_list.length == 0 ? "" : ", ") + ctor_arg_list.map {|arg| "#{arg}"}.join(", ")
% members = ctor_arg_list.map {|arg| "#{arg}_;"}.join("\n ")
% registers = op_map['reg'].map {|reg| "&#{reg}"}.join(", ")
% ops = (ops_list.length == 0 ? "" : ", ") + ops_list.map { |op| "#{op}_(#{op})"}.join(", ")
class <%= class_name %> : public <%= base_class %>
{
public:
explicit <%= class_name %>(<%= ctor_args %>) : <%= base_class %>(node)<%= ops %> {}
Formats GetFormats() const override {
return Span<const Format>(<%= get_format_name(insn.mnemonic) %>);
}
size_t Registers([[maybe_unused]] std::array<VReg*, MAX_REG_OPERAND>* regs) override
{
% reg_cnt = 0
% for reg in op_map['reg']
(*regs)[<%= reg_cnt %>] = &<%= reg %>;
% reg_cnt+=1;
% end
return <%= reg_cnt %>;
}
size_t Registers([[maybe_unused]] std::array<const VReg*, MAX_REG_OPERAND>* regs) const override
{
% reg_cnt = 0
% for reg in op_map['reg']
(*regs)[<%= reg_cnt %>] = &<%= reg %>;
% reg_cnt+=1;
% end
return <%= reg_cnt %>;
}
pandasm::Ins *Transform() const override
{
% pa_ins_args_list = Array.new
% ctor_arg_list.each do |arg|
% type = arg.split(" ")[0]
% name = arg.split(" ")[1]
% if type == "util::StringView"
% pa_ins_args_list.push("#{name}_.Mutf8()")
% elsif type == "Label*"
% pa_ins_args_list.push("#{name}_->Id()")
% else
% pa_ins_args_list.push("#{name}_")
% end
% end
return new pandasm::<%= class_name %>(<%= pa_ins_args_list.join(", ") %>);
}
ICSlot SetIcSlot(IcSizeType slot) override
{
% is_jit_ic = insn.properties.include?("jit_ic_slot")
% is_ic = (!is_jit_ic) && insn.properties.include?("ic_slot")
% is_8_bit_ic = insn.properties.include?("eight_bit_ic")
% is_16_bit_ic = (!is_8_bit_ic) && insn.properties.include?("sixteen_bit_ic")
% is_8_16_bit_ic = (!is_16_bit_ic) && insn.properties.include?("eight_sixteen_bit_ic")
% if (!is_jit_ic && !is_ic)
return 0;
% else
% ret = insn.properties.include?("one_slot") ? 1 : 2;
constexpr static ICSlot invalid = 0xFF;
% if (is_16_bit_ic || is_8_16_bit_ic)
if (slot <= 0xFF) {
if ((slot + <%= ret %>) > 0xFF) {
<%= op_map['imm'][0] %> = 0x100;
return <%= ret %> + (0x100 - slot);
}
<%= op_map['imm'][0] %> = slot;
return <%= ret %>;
}
if (slot > 0xFF && slot <= 0xFFFF) {
<%= op_map['imm'][0] %> = slot;
return <%= ret %>;
}
<%= op_map['imm'][0] %> = invalid;
return 0;
% end
% if (is_8_bit_ic)
if (slot <= 0xFF) {
if ((slot + <%= ret %>) > 0xFF) {
<%= op_map['imm'][0] %> = invalid;
return 0x100 - slot;
}
<%= op_map['imm'][0] %> = slot;
return <%= ret %>;
}
<%= op_map['imm'][0] %> = invalid;
return 0;
% end
% end
}
bool InlineCacheEnabled() override
{
% is_jit_ic = insn.properties.include?("jit_ic_slot")
% is_ic = (!is_jit_ic) && insn.properties.include?("ic_slot")
% if (!is_jit_ic && !is_ic)
return false;
% else
return true;
% end
}
ICSlot GetIcSlot() override
{
% is_jit_ic = insn.properties.include?("jit_ic_slot")
% is_ic = (!is_jit_ic) && insn.properties.include?("ic_slot")
% if (!is_jit_ic && !is_ic)
return 0;
% else
return <%= op_map['imm'][0] %>;
% end
}
bool oneByteSlotOnly() override
{
% is_jit_ic = insn.properties.include?("jit_ic_slot")
% is_ic = (!is_jit_ic) && insn.properties.include?("ic_slot")
% if (!is_jit_ic && !is_ic)
return false;
% end
% is_8_bit_ic = insn.properties.include?("eight_bit_ic")
% if (is_8_bit_ic)
return true;
% else
return false;
% end
}
uint8_t IcSlots() override
{
% is_jit_ic = insn.properties.include?("jit_ic_slot")
% is_ic = (!is_jit_ic) && insn.properties.include?("ic_slot")
% if (!is_jit_ic && !is_ic)
return 0;
% else
% ret = insn.properties.include?("one_slot") ? 1 : 2;
return <%= ret %>;
% end
}
% if is_range_op
bool IsRangeInst() const override
{
return true;
}
int64_t RangeRegsCount() override
{
% if insn.mnemonic == "createobjectwithexcludedkeys" or insn.mnemonic.start_with? "wide."
% if insn.mnemonic == "wide.callthisrange" or insn.mnemonic == "createobjectwithexcludedkeys" or
% insn.mnemonic == "wide.createobjectwithexcludedkeys" or insn.mnemonic == "wide.callthisrangewithname"
return <%= op_map['imm'][0] %> + 1;
% else
return <%= op_map['imm'][0] %>;
% end
% else
% if insn.mnemonic == "callthisrange" or insn.mnemonic == "callthisrangewithname"
return <%= op_map['imm'][1] %> + 1;
% else
return <%= op_map['imm'][1] %>;
% end
% end
}
% end
% if ops_list.length != 0
private:
<%= members %>
% end
};
% end
} // namespace panda::es2panda::compiler
#endif