//===-- WebAssemblyRegisterBankInfo.cpp -------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// \file /// This file implements the targeting of the RegisterBankInfo class for /// WebAssembly. /// \todo This should be generated by TableGen. //===----------------------------------------------------------------------===// #include "WebAssemblyRegisterBankInfo.h" #include "MCTargetDesc/WebAssemblyMCTargetDesc.h" #include "WebAssemblyRegisterInfo.h" #include "WebAssemblySubtarget.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/TargetRegisterInfo.h" #define GET_TARGET_REGBANK_IMPL #include "WebAssemblyGenRegisterBank.inc" namespace llvm { namespace WebAssembly { enum PartialMappingIdx { PMI_None = -1, PMI_I32 = 1, PMI_I64, PMI_Min = PMI_I32, }; const RegisterBankInfo::PartialMapping PartMappings[]{{0, 32, I32RegBank}, {0, 64, I64RegBank}}; } // namespace WebAssembly } // namespace llvm using namespace llvm; WebAssemblyRegisterBankInfo::WebAssemblyRegisterBankInfo( const TargetRegisterInfo &TRI) {} const RegisterBankInfo::InstructionMapping & WebAssemblyRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { unsigned Opc = MI.getOpcode(); const MachineFunction &MF = *MI.getParent()->getParent(); const MachineRegisterInfo &MRI = MF.getRegInfo(); if ((Opc != TargetOpcode::COPY && !isPreISelGenericOpcode(Opc)) || Opc == TargetOpcode::G_PHI) { const RegisterBankInfo::InstructionMapping &Mapping = getInstrMappingImpl(MI); if (Mapping.isValid()) return Mapping; } const unsigned NumOperands = MI.isCopyLike() ? 1 : MI.getNumOperands(); unsigned MappingID = DefaultMappingID; // Track the size and bank of each register. We don't do partial mappings. SmallVector OpSize(NumOperands); SmallVector OpRegBankIdx(NumOperands); for (unsigned Idx = 0; Idx < NumOperands; ++Idx) { auto &MO = MI.getOperand(Idx); if (!MO.isReg() || !MO.getReg()) continue; LLT Ty = MRI.getType(MO.getReg()); if (!Ty.isValid()) continue; OpSize[Idx] = Ty.getSizeInBits().getKnownMinValue(); if (Ty.isInteger()) { if (OpSize[Idx] == 32) { OpRegBankIdx[Idx] = WebAssembly::PMI_I32; } else if (OpSize[Idx] == 64) { OpRegBankIdx[Idx] = WebAssembly::PMI_I64; } } } SmallVector OpdsMapping(NumOperands); for (unsigned Idx = 0; Idx < NumOperands; ++Idx) { if (MI.getOperand(Idx).isReg() && MI.getOperand(Idx).getReg()) { LLT Ty = MRI.getType(MI.getOperand(Idx).getReg()); if (!Ty.isValid()) continue; if (OpRegBankIdx[Idx] <= 0) { return getInvalidInstructionMapping(); } const auto &Mapping = getValueMapping( &WebAssembly::PartMappings[OpRegBankIdx[Idx] - WebAssembly::PMI_Min], 1); if (!Mapping.isValid()) return getInvalidInstructionMapping(); OpdsMapping[Idx] = &Mapping; } } return getInstructionMapping(MappingID, /*Cost=*/1, getOperandsMapping(OpdsMapping), NumOperands); }