1//===-- WebAssemblyRegisterBankInfo.cpp -------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8/// \file
9/// This file implements the targeting of the RegisterBankInfo class for
10/// WebAssembly.
11/// \todo This should be generated by TableGen.
12//===----------------------------------------------------------------------===//
13
14#include "WebAssemblyRegisterBankInfo.h"
15#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
16#include "WebAssemblyRegisterInfo.h"
17#include "WebAssemblySubtarget.h"
18#include "llvm/CodeGen/MachineRegisterInfo.h"
19#include "llvm/CodeGen/TargetRegisterInfo.h"
20
21#define GET_TARGET_REGBANK_IMPL
22
23#include "WebAssemblyGenRegisterBank.inc"
24
25namespace llvm {
26namespace WebAssembly {
27enum PartialMappingIdx {
28 PMI_None = -1,
29 PMI_I32 = 1,
30 PMI_I64,
31 PMI_F32,
32 PMI_F64,
33 PMI_Min = PMI_I32,
34};
35
36const RegisterBankInfo::PartialMapping PartMappings[]{{0, 32, I32RegBank},
37 {0, 64, I64RegBank},
38 {0, 32, F32RegBank},
39 {0, 64, F64RegBank}};
40
41} // namespace WebAssembly
42} // namespace llvm
43
44using namespace llvm;
45
46WebAssemblyRegisterBankInfo::WebAssemblyRegisterBankInfo(
47 const TargetRegisterInfo &TRI) {}
48
49const RegisterBankInfo::InstructionMapping &
50WebAssemblyRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
51 unsigned Opc = MI.getOpcode();
52 const MachineFunction &MF = *MI.getParent()->getParent();
53 const MachineRegisterInfo &MRI = MF.getRegInfo();
54
55 if ((Opc != TargetOpcode::COPY && !isPreISelGenericOpcode(Opcode: Opc)) ||
56 Opc == TargetOpcode::G_PHI) {
57 const RegisterBankInfo::InstructionMapping &Mapping =
58 getInstrMappingImpl(MI);
59 if (Mapping.isValid())
60 return Mapping;
61 }
62
63 const unsigned NumOperands = MI.isCopyLike() ? 1 : MI.getNumOperands();
64 unsigned MappingID = DefaultMappingID;
65
66 // Track the size and bank of each register. We don't do partial mappings.
67 SmallVector<unsigned, 8> OpSize(NumOperands);
68 SmallVector<WebAssembly::PartialMappingIdx, 8> OpRegBankIdx(NumOperands);
69 for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
70 auto &MO = MI.getOperand(i: Idx);
71 if (!MO.isReg() || !MO.getReg())
72 continue;
73
74 LLT Ty = MRI.getType(Reg: MO.getReg());
75 if (!Ty.isValid())
76 continue;
77
78 OpSize[Idx] = Ty.getSizeInBits().getKnownMinValue();
79
80 if (Ty.isInteger()) {
81 if (OpSize[Idx] == 32) {
82 OpRegBankIdx[Idx] = WebAssembly::PMI_I32;
83 } else if (OpSize[Idx] == 64) {
84 OpRegBankIdx[Idx] = WebAssembly::PMI_I64;
85 }
86 } else if (Ty.isFloatIEEE()) {
87 if (OpSize[Idx] == 32) {
88 OpRegBankIdx[Idx] = WebAssembly::PMI_F32;
89 } else if (OpSize[Idx] == 64) {
90 OpRegBankIdx[Idx] = WebAssembly::PMI_F64;
91 }
92 }
93 }
94
95 SmallVector<const ValueMapping *, 8> OpdsMapping(NumOperands);
96 for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
97 if (MI.getOperand(i: Idx).isReg() && MI.getOperand(i: Idx).getReg()) {
98 LLT Ty = MRI.getType(Reg: MI.getOperand(i: Idx).getReg());
99 if (!Ty.isValid())
100 continue;
101
102 if (OpRegBankIdx[Idx] <= 0) {
103 return getInvalidInstructionMapping();
104 }
105
106 const auto &Mapping = getValueMapping(
107 BreakDown: &WebAssembly::PartMappings[OpRegBankIdx[Idx] - WebAssembly::PMI_Min],
108 NumBreakDowns: 1);
109
110 if (!Mapping.isValid())
111 return getInvalidInstructionMapping();
112
113 OpdsMapping[Idx] = &Mapping;
114 }
115 }
116
117 return getInstructionMapping(ID: MappingID, /*Cost=*/1,
118 OperandsMapping: getOperandsMapping(OpdsMapping), NumOperands);
119}
120