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 "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_Min = PMI_I32,
31};
32
33enum ValueMappingIdx {
34 InvalidIdx = 0,
35 I32Idx = 1,
36 I64Idx = 5,
37};
38
39const RegisterBankInfo::PartialMapping PartMappings[]{{0, 32, I32RegBank},
40 {0, 64, I64RegBank}};
41
42const RegisterBankInfo::ValueMapping ValueMappings[] = {
43 // invalid
44 {nullptr, 0},
45 // up to 4 operands as I32
46 {&PartMappings[PMI_I32 - PMI_Min], 1},
47 {&PartMappings[PMI_I32 - PMI_Min], 1},
48 {&PartMappings[PMI_I32 - PMI_Min], 1},
49 {&PartMappings[PMI_I32 - PMI_Min], 1},
50 // up to 4 operands as I64
51 {&PartMappings[PMI_I64 - PMI_Min], 1},
52 {&PartMappings[PMI_I64 - PMI_Min], 1},
53 {&PartMappings[PMI_I64 - PMI_Min], 1},
54 {&PartMappings[PMI_I64 - PMI_Min], 1},
55};
56} // namespace WebAssembly
57} // namespace llvm
58
59using namespace llvm;
60
61WebAssemblyRegisterBankInfo::WebAssemblyRegisterBankInfo(
62 const TargetRegisterInfo &TRI) {}
63
64const RegisterBankInfo::InstructionMapping &
65WebAssemblyRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
66 unsigned Opc = MI.getOpcode();
67 const MachineFunction &MF = *MI.getParent()->getParent();
68 const MachineRegisterInfo &MRI = MF.getRegInfo();
69
70 if ((Opc != TargetOpcode::COPY && !isPreISelGenericOpcode(Opcode: Opc)) ||
71 Opc == TargetOpcode::G_PHI) {
72 const RegisterBankInfo::InstructionMapping &Mapping =
73 getInstrMappingImpl(MI);
74 if (Mapping.isValid())
75 return Mapping;
76 }
77
78 const unsigned NumOperands = MI.getNumOperands();
79 const ValueMapping *OperandsMapping = nullptr;
80 unsigned MappingID = DefaultMappingID;
81
82 const LLT Op0Ty = MRI.getType(Reg: MI.getOperand(i: 0).getReg());
83 unsigned Op0Size = Op0Ty.getSizeInBits();
84
85 auto &Op0IntValueMapping =
86 WebAssembly::ValueMappings[Op0Size == 64 ? WebAssembly::I64Idx
87 : WebAssembly::I32Idx];
88
89 using namespace TargetOpcode;
90 switch (Opc) {
91 case G_ADD:
92 case G_AND:
93 case G_ASHR:
94 case G_SHL:
95 OperandsMapping = &Op0IntValueMapping;
96 break;
97 case G_CONSTANT:
98 OperandsMapping = getOperandsMapping(OpdsMapping: {&Op0IntValueMapping, nullptr});
99 break;
100 }
101
102 if (!OperandsMapping)
103 return getInvalidInstructionMapping();
104
105 return getInstructionMapping(ID: MappingID, /*Cost=*/1, OperandsMapping,
106 NumOperands);
107}
108