1/* 2 * Copyright (c) 2021-2022 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#define PANDA_INSTRUCTION_LIST(_) \ 17% Panda::instructions.group_by(&:mnemonic).each do |mnemonic, group| 18% insn = group.first 19% formats = group.map(&:format) 20% pretty_format = insn.format.pretty.upcase.gsub(/[0-9]/, '') 21% pretty_format.gsub!('IMM', 'ID') if insn.jump? 22% pretty_format.gsub!('ID', 'TYPE') if insn.properties.include?('type_id') 23% 24% flags = ["InstFlags::NONE"] 25% flags << "InstFlags::CALL" if insn.simple_call? 26% flags << "InstFlags::JUMP" if insn.jump? 27% flags << "InstFlags::COND" if insn.conditional? 28% flags << "InstFlags::RETURN" if insn.return? 29% flags << "InstFlags::ACC_READ" if insn.acc_read? 30% flags << "InstFlags::ACC_WRITE" if insn.acc_write? 31% flags << "InstFlags::THROWING" if insn.throwing? 32% flags << "InstFlags::METHOD_ID" if insn.properties.include? 'method_id' 33% flags << "InstFlags::FIELD_ID" if insn.properties.include? 'field_id' 34% flags << "InstFlags::TYPE_ID" if insn.properties.include? 'type_id' 35% flags << "InstFlags::STRING_ID" if insn.properties.include? 'string_id' 36% flags << "InstFlags::LITERALARRAY_ID" if insn.properties.include? 'literalarray_id' 37% flags << "InstFlags::CALL_RANGE" if (insn.properties.include?('call') || insn.stripped_mnemonic == 'initobj') && insn.range? 38% flags = "(#{flags.join(" | ")})" 39% 40% max_width = group.map do |i| 41% i.operands.select(&:reg?).map(&:width).max 42% end.max 43% max_width ||= 0 44% 45% regs = insn.operands.select(&:reg?) 46% dst_idx = regs.index(&:dst?) || 'INVALID_REG_IDX' 47% use_idxs = regs.size.times.select { |idx| regs[idx].src? } || [] 48% use_idxs += (['INVALID_REG_IDX'] * (max_number_of_src_regs - use_idxs.size)) 49% use_idxs = "(std::array<int, #{ max_number_of_src_regs }>{{#{use_idxs.join(', ')}}})" 50% 51_(<%= insn.asm_token %>, "<%= insn.mnemonic %>", <%= pretty_format %>, <%= max_width %>, <%= flags %>, <%= dst_idx %>, <%= use_idxs %>) \ 52% end 53% Panda::pseudo_instructions.each do |insn| 54% use_idxs = insn.use_idxs + ['INVALID_REG_IDX'] * (max_number_of_src_regs - insn.use_idxs.size) 55% use_idxs = "(std::array<int, #{max_number_of_src_regs}>{{#{use_idxs.join(', ')}}})" 56_(<%= insn.opcode %> , "<%= insn.opcode %>", NONE, 0, (<%= insn.flags.join(" | ") %>), <%= insn.dst_idx %>, <%= use_idxs %>) \ 57% end 58 59