| //===-- 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 "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_F32, | |
| PMI_F64, | |
| PMI_Min = PMI_I32, | |
| }; | |
| const RegisterBankInfo::PartialMapping PartMappings[]{{0, 32, I32RegBank}, | |
| {0, 64, I64RegBank}, | |
| {0, 32, F32RegBank}, | |
| {0, 64, F64RegBank}}; | |
| } // 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<unsigned, 8> OpSize(NumOperands); | |
| SmallVector<WebAssembly::PartialMappingIdx, 8> 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() || (Ty.isPointer() && Ty.getAddressSpace() == 0)) { | |
| if (OpSize[Idx] == 32) { | |
| OpRegBankIdx[Idx] = WebAssembly::PMI_I32; | |
| } else if (OpSize[Idx] == 64) { | |
| OpRegBankIdx[Idx] = WebAssembly::PMI_I64; | |
| } | |
| } else if (Ty.isFloatIEEE()) { | |
| if (OpSize[Idx] == 32) { | |
| OpRegBankIdx[Idx] = WebAssembly::PMI_F32; | |
| } else if (OpSize[Idx] == 64) { | |
| OpRegBankIdx[Idx] = WebAssembly::PMI_F64; | |
| } | |
| } | |
| } | |
| SmallVector<const ValueMapping *, 8> 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); | |
| } |