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