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