1# Copyright (c) 2021-2022 Huawei Device Co., Ltd. 2# Licensed under the Apache License, Version 2.0 (the "License"); 3# you may not use this file except in compliance with the License. 4# You may obtain a copy of the License at 5# 6# http://www.apache.org/licenses/LICENSE-2.0 7# 8# Unless required by applicable law or agreed to in writing, software 9# distributed under the License is distributed on an "AS IS" BASIS, 10# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11# See the License for the specific language governing permissions and 12# limitations under the License. 13 14require 'ostruct' 15 16# PandaFile specific extension of ISAPI 17 18Instruction.class_eval do 19 def emitter_name 20 mnemonic.split('.').map { |p| p == '64' ? 'Wide' : p.capitalize }.join 21 end 22 23 def each_operand 24 getters = {:reg? => 0, :imm? => 0, :id? => 0} 25 operands.each do |op| 26 key = getters.keys.find { |x| op.send(x) } 27 yield op, getters[key] 28 getters[key] += 1 29 end 30 end 31 32 def jcmp? 33 jump? && conditional? && stripped_mnemonic[-1] != 'z' 34 end 35 36 def jcmpz? 37 jump? && conditional? && stripped_mnemonic[-1] == 'z' 38 end 39end 40 41Operand.class_eval do 42 def to_h 43 instance_variables.map { |v| [v.to_s[1..-1], instance_variable_get(v)] }.to_h 44 end 45end 46 47def storage_width(bits) 48 (bits + 7) / 8 * 8 49end 50 51def format_ops(format) 52 format.encoding.values.map(&:dup) 53end 54 55# returns array of OpenStruct with fields 56# name - name of variable in emitter code 57# type - type of variable in emitter code 58# width - bit width 59# tag - the same as in Operand isapi class 60def emitter_signature(group, is_jump) 61 sig = format_ops(group.first.format).each { |o| o.width = storage_width(o.width) } 62 group.each do |insn| 63 insn.operands.each_with_index do |o, i| 64 sig[i].width = [o.width, sig[i].width].max 65 end 66 end 67 sig.each do |o| 68 if o.name.start_with?('imm') 69 o.type, o.name = is_jump ? ['const Label &', 'label'] : ["int#{o.width}_t", o.name] 70 else 71 o.type = "uint#{o.width}_t" 72 end 73 end 74end 75 76def insns_uniq_sort_fmts 77 Panda.instructions.uniq { |i| i.format.pretty }.sort_by { |insn| insn.format.pretty } 78end 79