1 //===- X86RegisterBankInfo.cpp -----------------------------------*- C++ -*-==//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 /// This file implements the targeting of the RegisterBankInfo class for X86.
11 /// \todo This should be generated by TableGen.
12 //===----------------------------------------------------------------------===//
14 #include "X86RegisterBankInfo.h"
15 #include "X86InstrInfo.h"
16 #include "llvm/CodeGen/GlobalISel/RegisterBank.h"
17 #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
18 #include "llvm/CodeGen/MachineRegisterInfo.h"
19 #include "llvm/Target/TargetRegisterInfo.h"
21 #define GET_TARGET_REGBANK_IMPL
22 #include "X86GenRegisterBank.inc"
24 // This file will be TableGen'ed at some point.
25 #include "X86GenRegisterBankInfo.def"
29 #ifndef LLVM_BUILD_GLOBAL_ISEL
30 #error "You shouldn't build this"
33 X86RegisterBankInfo::X86RegisterBankInfo(const TargetRegisterInfo &TRI)
34 : X86GenRegisterBankInfo() {
36 // validate RegBank initialization.
37 const RegisterBank &RBGPR = getRegBank(X86::GPRRegBankID);
39 assert(&X86::GPRRegBank == &RBGPR && "Incorrect RegBanks inizalization.");
41 // The GPR register bank is fully defined by all the registers in
42 // GR64 + its subclasses.
43 assert(RBGPR.covers(*TRI.getRegClass(X86::GR64RegClassID)) &&
44 "Subclass not added?");
45 assert(RBGPR.getSize() == 64 && "GPRs should hold up to 64-bit");
48 const RegisterBank &X86RegisterBankInfo::getRegBankFromRegClass(
49 const TargetRegisterClass &RC) const {
51 if (X86::GR8RegClass.hasSubClassEq(&RC) ||
52 X86::GR16RegClass.hasSubClassEq(&RC) ||
53 X86::GR32RegClass.hasSubClassEq(&RC) ||
54 X86::GR64RegClass.hasSubClassEq(&RC))
55 return getRegBank(X86::GPRRegBankID);
57 llvm_unreachable("Unsupported register kind yet.");
60 RegisterBankInfo::InstructionMapping
61 X86RegisterBankInfo::getOperandsMapping(const MachineInstr &MI, bool isFP) {
62 const MachineFunction &MF = *MI.getParent()->getParent();
63 const MachineRegisterInfo &MRI = MF.getRegInfo();
65 unsigned NumOperands = MI.getNumOperands();
66 LLT Ty = MRI.getType(MI.getOperand(0).getReg());
68 if (NumOperands != 3 ||
69 (Ty != MRI.getType(MI.getOperand(1).getReg())) ||
70 (Ty != MRI.getType(MI.getOperand(2).getReg())))
71 llvm_unreachable("Unsupported operand maping yet.");
73 ValueMappingIdx ValMapIdx = VMI_None;
75 switch (Ty.getSizeInBits()) {
77 ValMapIdx = VMI_3OpsGpr8Idx;
80 ValMapIdx = VMI_3OpsGpr16Idx;
83 ValMapIdx = VMI_3OpsGpr32Idx;
86 ValMapIdx = VMI_3OpsGpr64Idx;
89 llvm_unreachable("Unsupported register size.");
93 llvm_unreachable("Floating point not supported yet.");
96 return InstructionMapping{DefaultMappingID, 1, &ValMappings[ValMapIdx],
100 RegisterBankInfo::InstructionMapping
101 X86RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
102 auto Opc = MI.getOpcode();
104 // Try the default logic for non-generic instructions that are either copies
105 // or already have some operands assigned to banks.
106 if (!isPreISelGenericOpcode(Opc)) {
107 InstructionMapping Mapping = getInstrMappingImpl(MI);
108 if (Mapping.isValid())
113 case TargetOpcode::G_ADD:
114 case TargetOpcode::G_SUB:
115 return getOperandsMapping(MI, false);
118 return InstructionMapping{};
121 return InstructionMapping{};