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 14# Assembler specific extension of ISAPI 15Instruction.class_eval do 16 def asm_token 17 mnemonic.tr('.', '_').upcase 18 end 19 20 def call? 21 properties.include?('call') 22 end 23 24 def range? 25 mnemonic.split('.')[-1] == 'range' 26 end 27 28 def simple_call? 29 call? && !range? && !properties.include?('dynamic') 30 end 31 32 def return? 33 stripped_mnemonic == 'return' 34 end 35 36 def return_obj? 37 mnemonic == 'return.obj' 38 end 39 40 def return64? 41 mnemonic == 'return.64' 42 end 43 44 def return32? 45 mnemonic == 'return' 46 end 47 48 def return_void? 49 mnemonic == 'return.void' 50 end 51end 52 53def bit_cast(what, to_type, from_type) 54 "bit_cast<#{to_type}, #{from_type}>(static_cast<#{from_type}>(std::get<double>(#{what})))" 55end 56 57def index_of_max(a) 58 a.each_with_index.max[1] # returns index of `last` max value 59end 60 61def max_number_of_src_regs 62 Panda::instructions.map do |insn| 63 insn.operands.select(&:reg?).select(&:src?).size 64 end.max 65end 66 67IR = Struct.new(:opcode, :flags, :dst_idx, :use_idxs) 68 69module Panda 70 def self.pseudo_instructions 71 insns = [] 72 insns << IR.new('MOVX', ['InstFlags::PSEUDO'], 0, [1]) 73 insns << IR.new('LDAX', ['InstFlags::PSEUDO', 'InstFlags::ACC_WRITE'], 'INVALID_REG_IDX', [0]) 74 insns << IR.new('STAX', ['InstFlags::PSEUDO', 'InstFlags::ACC_READ'], 0, []) 75 insns << IR.new('NEWX', ['InstFlags::PSEUDO'], 0, []) 76 insns << IR.new('INITOBJX', ['InstFlags::PSEUDO', 'InstFlags::CALL', 'InstFlags::ACC_WRITE'], 'INVALID_REG_IDX', []) 77 insns << IR.new('CALLX', ['InstFlags::PSEUDO', 'InstFlags::CALL', 'InstFlags::ACC_WRITE'], 'INVALID_REG_IDX', []) 78 insns << IR.new('CALLX_VIRT', ['InstFlags::PSEUDO', 'InstFlags::CALL', 'InstFlags::ACC_WRITE'], 'INVALID_REG_IDX', []) 79 insns << IR.new('B_P_CALLIX', ['InstFlags::PSEUDO', 'InstFlags::CALL', 'InstFlags::ACC_WRITE'], 'INVALID_REG_IDX', []) 80 insns << IR.new('B_P_CALLIEX',['InstFlags::PSEUDO', 'InstFlags::CALL', 'InstFlags::ACC_WRITE'], 'INVALID_REG_IDX', []) 81 insns 82 end 83end 84 85# returns array of OpenStruct with fields 86# name - name of variable in emitter code 87# type - type of variable in emitter code 88def assembler_signature(group, is_jump) 89 insn = group.first 90 format_ops(insn.format).each do |o| 91 if o.name.start_with?('imm') 92 if insn.asm_token.start_with?('F') 93 o.type, o.name = is_jump ? ['const std::string &', 'label'] : ['double', o.name] 94 else 95 o.type, o.name = is_jump ? ['const std::string &', 'label'] : ['int64_t', o.name] 96 end 97 elsif o.name.start_with?('id') 98 o.type, o.name = ['const std::string &', o.name] 99 else 100 o.type = 'uint16_t' 101 end 102 end 103end 104