blob: 7e50ca6ab22fe8bcdbb75c640f1c4b29449a3db7 [file] [edit]
//===-- 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_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()) {
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);
}