1/* 2 * Copyright (c) 2021-2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#ifndef _PANDA_ASSEMBLY_ISA_H 17#define _PANDA_ASSEMBLY_ISA_H 18 19 constexpr size_t MAX_NUMBER_OF_SRC_REGS = <%= max_number_of_src_regs %>; 20 21// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 22#define PANDA_INSTRUCTION_LIST(_) \ 23% Panda::instructions.group_by(&:mnemonic).each do |mnemonic, group| 24% insn = group.first 25% formats = group.map(&:format) 26% pretty_format = insn.format.pretty.upcase.gsub(/[0-9]/, '') 27% pretty_format.gsub!('IMM', 'ID') if insn.jump? 28% pretty_format.gsub!('ID', 'TYPE') if insn.properties.include?('type_id') 29% 30% flags = ["InstFlags::NONE"] 31% flags << "InstFlags::CALL" if insn.simple_call? 32% flags << "InstFlags::JUMP" if insn.jump? 33% flags << "InstFlags::COND" if insn.conditional? 34% flags << "InstFlags::RETURN" if insn.return? 35% flags << "InstFlags::ACC_READ" if insn.acc_read? 36% flags << "InstFlags::ACC_WRITE" if insn.acc_write? 37% flags << "InstFlags::THROWING" if insn.throwing? 38% flags << "InstFlags::METHOD_ID" if insn.properties.include? 'method_id' 39% flags << "InstFlags::STATIC_METHOD_ID" if insn.properties.include? 'static_method_id' 40% flags << "InstFlags::FIELD_ID" if insn.properties.include? 'field_id' 41% flags << "InstFlags::STATIC_FIELD_ID" if insn.properties.include? 'static_field_id' 42% flags << "InstFlags::TYPE_ID" if insn.properties.include? 'type_id' 43% flags << "InstFlags::STRING_ID" if insn.properties.include? 'string_id' 44% flags << "InstFlags::LITERALARRAY_ID" if insn.properties.include? 'literalarray_id' 45% flags << "InstFlags::CALL_RANGE" if (insn.properties.include?('call') || insn.stripped_mnemonic == 'initobj') && insn.range? 46% flags = "(#{flags.join(" | ")})" 47% 48% max_width = group.map do |i| 49% i.operands.select(&:reg?).map(&:width).max 50% end.max 51% max_width ||= 0 52% 53% profile_size = insn.profiled? ? Panda::profiles[insn.profile.name].size : 0 54% 55% regs = insn.operands.select(&:reg?) 56% dst_idx = regs.index(&:dst?) || 'INVALID_REG_IDX' 57% use_idxs = regs.size.times.select { |idx| regs[idx].src? } || [] 58% use_idxs += (['INVALID_REG_IDX'] * (max_number_of_src_regs - use_idxs.size)) 59% use_idxs = "(std::array<int, #{ max_number_of_src_regs }>{{#{use_idxs.join(', ')}}})" 60% 61_(<%= insn.asm_token %>, "<%= insn.mnemonic %>", <%= pretty_format %>, <%= max_width %>, <%= flags %>, <%= dst_idx %>, <%= use_idxs %>, <%= profile_size %>) \ 62% end 63% Panda::pseudo_instructions.each do |insn| 64% use_idxs = insn.use_idxs + ['INVALID_REG_IDX'] * (max_number_of_src_regs - insn.use_idxs.size) 65% use_idxs = "(std::array<int, #{max_number_of_src_regs}>{{#{use_idxs.join(', ')}}})" 66_(<%= insn.opcode %> , "<%= insn.opcode %>", NONE, 0, (<%= insn.flags.join(" | ") %>), <%= insn.dst_idx %>, <%= use_idxs %>, 0) \ 67% end 68 69#endif // !_PANDA_ASSEMBLY_ISA_H 70