1/* 2 * Copyright (c) 2021-2024 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::FIELD_ID" if insn.properties.include? 'field_id' 40% flags << "InstFlags::TYPE_ID" if insn.properties.include? 'type_id' 41% flags << "InstFlags::STRING_ID" if insn.properties.include? 'string_id' 42% flags << "InstFlags::LITERALARRAY_ID" if insn.properties.include? 'literalarray_id' 43% flags << "InstFlags::CALL_RANGE" if (insn.properties.include?('call') || insn.stripped_mnemonic == 'initobj') && insn.range? 44% flags = "(#{flags.join(" | ")})" 45% 46% max_width = group.map do |i| 47% i.operands.select(&:reg?).map(&:width).max 48% end.max 49% max_width ||= 0 50% 51% profile_size = insn.profiled? ? Panda::profiles[insn.profile.name].size : 0 52% 53% regs = insn.operands.select(&:reg?) 54% dst_idx = regs.index(&:dst?) || 'INVALID_REG_IDX' 55% use_idxs = regs.size.times.select { |idx| regs[idx].src? } || [] 56% use_idxs += (['INVALID_REG_IDX'] * (max_number_of_src_regs - use_idxs.size)) 57% use_idxs = "(std::array<int, #{ max_number_of_src_regs }>{{#{use_idxs.join(', ')}}})" 58% 59_(<%= insn.asm_token %>, "<%= insn.mnemonic %>", <%= pretty_format %>, <%= max_width %>, <%= flags %>, <%= dst_idx %>, <%= use_idxs %>, <%= profile_size %>) \ 60% end 61% Panda::pseudo_instructions.each do |insn| 62% use_idxs = insn.use_idxs + ['INVALID_REG_IDX'] * (max_number_of_src_regs - insn.use_idxs.size) 63% use_idxs = "(std::array<int, #{max_number_of_src_regs}>{{#{use_idxs.join(', ')}}})" 64_(<%= insn.opcode %> , "<%= insn.opcode %>", NONE, 0, (<%= insn.flags.join(" | ") %>), <%= insn.dst_idx %>, <%= use_idxs %>, 0) \ 65% end 66 67#endif // !_PANDA_ASSEMBLY_ISA_H 68