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