% def get_node_kind(mnemonic) % return "#{mnemonic.gsub('.', '_').upcase}" % end % % def get_format_name(mnemonic) % return "#{mnemonic.gsub('.', '_').upcase}" + "_FORMATS" % end /** * Copyright (c) 2021-2022 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 #include #include 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(nullptr, nullptr); } const std::string &Id() const { return id_; } size_t Registers([[maybe_unused]] std::array* regs) override { return 0; } size_t Registers([[maybe_unused]] std::array* regs) const override { return 0; } void Transform(pandasm::Ins *ins) const override { ins->opcode = pandasm::Opcode::INVALID; ins->set_label = true; ins->label = id_; } ICSlot SetIcSlot(IcSizeType currentSlot) 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" % 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(<%= get_format_name(insn.mnemonic) %>); } size_t Registers([[maybe_unused]] std::array* 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* regs) const override { % reg_cnt = 0 % for reg in op_map['reg'] (*regs)[<%= reg_cnt %>] = &<%= reg %>; % reg_cnt+=1; % end return <%= reg_cnt %>; } void Transform(pandasm::Ins* ins) const override { ins->opcode = pandasm::Opcode::<%= node_kind %>; % if op_map['reg'].length != 0 ins->regs.reserve(<%= op_map['reg'].length %>); % end % if op_map['imm'].length != 0 ins->imms.reserve(<%= op_map['imm'].length %>); % end % if op_map['str'].length + op_map['lbl'].length != 0 ins->ids.reserve(<%= op_map['str'].length + op_map['lbl'].length %>); % end % for reg in op_map['reg'] ins->regs.emplace_back(<%= reg %>); % end % for imm in op_map['imm'] ins->imms.emplace_back(<%= imm %>); % end % for str in op_map['str'] ins->ids.emplace_back(<%= str %>.Mutf8()); % end % for lbl in op_map['lbl'] ins->ids.emplace_back(<%= lbl %>->Id()); % end } ICSlot SetIcSlot(IcSizeType slot) 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; constexpr static ICSlot invalid = 0xFF; % if (is_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_jit_ic && !is_ic) if (slot < 0xFF) { if ((slot + <%= ret %>) > 0xFF) { <%= op_map['imm'][0] %> = invalid; return 0; } <%= op_map['imm'][0] %> = slot; return <%= ret %>; } <%= op_map['imm'][0] %> = invalid; return 0; % end % 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" return <%= op_map['imm'][0] %> + 1; % else return <%= op_map['imm'][0] %>; % end % else % if insn.mnemonic == "callthisrange" 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