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