• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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