diff --git a/llvm/lib/Target/M68k/GlSel/M68kRegisterBankInfo.cpp b/llvm/lib/Target/M68k/GlSel/M68kRegisterBankInfo.cpp index d124786246556..5c0f5dae8e372 100644 --- a/llvm/lib/Target/M68k/GlSel/M68kRegisterBankInfo.cpp +++ b/llvm/lib/Target/M68k/GlSel/M68kRegisterBankInfo.cpp @@ -11,7 +11,8 @@ //===----------------------------------------------------------------------===// #include "M68kRegisterBankInfo.h" -#include "MCTargetDesc/M68kMCTargetDesc.h" +#include "M68kInstrInfo.h" // For the register classes +#include "M68kSubtarget.h" #include "llvm/CodeGen/GlobalISel/RegisterBank.h" #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" @@ -19,9 +20,86 @@ #define GET_TARGET_REGBANK_IMPL #include "M68kGenRegisterBank.inc" -#undef GET_TARGET_REGBANK_IMPL using namespace llvm; +// FIXME: TableGen this. +// If it grows too much and TableGen still isn't ready to do the job, extract it +// into an M68kGenRegisterBankInfo.def (similar to AArch64). +namespace llvm { +namespace M68k { +enum PartialMappingIdx { + PMI_GPR, + PMI_Min = PMI_GPR, +}; + +RegisterBankInfo::PartialMapping PartMappings[]{ + // GPR Partial Mapping + {0, 32, GPRRegBank}, +}; + +enum ValueMappingIdx { + InvalidIdx = 0, + GPR3OpsIdx = 1, +}; + +RegisterBankInfo::ValueMapping ValueMappings[] = { + // invalid + {nullptr, 0}, + // 3 operands in GPRs + {&PartMappings[PMI_GPR - PMI_Min], 1}, + {&PartMappings[PMI_GPR - PMI_Min], 1}, + {&PartMappings[PMI_GPR - PMI_Min], 1}, + +}; +} // end namespace M68k +} // end namespace llvm + M68kRegisterBankInfo::M68kRegisterBankInfo(const TargetRegisterInfo &TRI) : M68kGenRegisterBankInfo() {} + +const RegisterBank & +M68kRegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC, + LLT) const { + return getRegBank(M68k::GPRRegBankID); +} + +const RegisterBankInfo::InstructionMapping & +M68kRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { + auto Opc = MI.getOpcode(); + + if (!isPreISelGenericOpcode(Opc)) { + const InstructionMapping &Mapping = getInstrMappingImpl(MI); + if (Mapping.isValid()) + return Mapping; + } + + using namespace TargetOpcode; + + unsigned NumOperands = MI.getNumOperands(); + const ValueMapping *OperandsMapping = &M68k::ValueMappings[M68k::GPR3OpsIdx]; + + switch (Opc) { + case G_ADD: + case G_SUB: + case G_MUL: + case G_SDIV: + case G_UDIV: + case G_LOAD: + case G_STORE: { + OperandsMapping = &M68k::ValueMappings[M68k::GPR3OpsIdx]; + break; + } + + case G_CONSTANT: + case G_FRAME_INDEX: + OperandsMapping = + getOperandsMapping({&M68k::ValueMappings[M68k::GPR3OpsIdx], nullptr}); + break; + default: + return getInvalidInstructionMapping(); + } + + return getInstructionMapping(DefaultMappingID, /*Cost=*/1, OperandsMapping, + NumOperands); +} diff --git a/llvm/lib/Target/M68k/GlSel/M68kRegisterBankInfo.h b/llvm/lib/Target/M68k/GlSel/M68kRegisterBankInfo.h index 9b97cc4a6dd42..853c75df2bb32 100644 --- a/llvm/lib/Target/M68k/GlSel/M68kRegisterBankInfo.h +++ b/llvm/lib/Target/M68k/GlSel/M68kRegisterBankInfo.h @@ -34,6 +34,12 @@ class M68kGenRegisterBankInfo : public RegisterBankInfo { class M68kRegisterBankInfo final : public M68kGenRegisterBankInfo { public: M68kRegisterBankInfo(const TargetRegisterInfo &TRI); + + const RegisterBank &getRegBankFromRegClass(const TargetRegisterClass &RC, + LLT) const override; + + const InstructionMapping & + getInstrMapping(const MachineInstr &MI) const override; }; } // end namespace llvm #endif diff --git a/llvm/lib/Target/M68k/GlSel/M68kRegisterBanks.td b/llvm/lib/Target/M68k/GlSel/M68kRegisterBanks.td index 2d1e74f784808..942677a60e6c9 100644 --- a/llvm/lib/Target/M68k/GlSel/M68kRegisterBanks.td +++ b/llvm/lib/Target/M68k/GlSel/M68kRegisterBanks.td @@ -12,4 +12,4 @@ //===----------------------------------------------------------------------===// /// General Purpose Registers. Here we define a register bank with name AnyGPR -def GPRRegBank : RegisterBank<"AnyGPR", [DR8]>; +def GPRRegBank : RegisterBank<"AnyGPR", [XR32]>; diff --git a/llvm/test/CodeGen/M68k/GlobalISel/reg_bank_test.ll b/llvm/test/CodeGen/M68k/GlobalISel/reg_bank_test.ll new file mode 100644 index 0000000000000..5c8d0137d422b --- /dev/null +++ b/llvm/test/CodeGen/M68k/GlobalISel/reg_bank_test.ll @@ -0,0 +1,29 @@ +; RUN: llc -mtriple=m68k -global-isel -stop-after=regbankselect < %s | FileCheck %s + +define i32 @test_add(i32 %x, i32 %y) { + ; CHECK-LABEL: name: test_add + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: [[G_F_I1:%[0-9]+]]:anygpr(p0) = G_FRAME_INDEX + ; CHECK: [[G_LOAD1:%[0-9]+]]:anygpr(s32) = G_LOAD [[G_F_I1]](p0) + ; CHECK: [[G_F_I2:%[0-9]+]]:anygpr(p0) = G_FRAME_INDEX + ; CHECK: [[G_LOAD2:%[0-9]+]]:anygpr(s32) = G_LOAD [[G_F_I2]](p0) + ; CHECK: [[G_ADD1:%[0-9]+]]:anygpr(s32) = G_ADD [[G_LOAD1]], [[G_LOAD2]] + ; CHECK: $d0 = COPY [[G_ADD1]](s32) + ; CHECK: RTS implicit $d0 + %sum = add i32 %x, %y + ret i32 %sum +} + +define i32 @test_sub(i32 %x, i32 %y) { + ; CHECK-LABEL: name: test_sub + ; CHECK: bb.1 (%ir-block.0): + ; CHECK: [[G_F_I1:%[0-9]+]]:anygpr(p0) = G_FRAME_INDEX + ; CHECK: [[G_LOAD1:%[0-9]+]]:anygpr(s32) = G_LOAD [[G_F_I1]](p0) + ; CHECK: [[G_F_I2:%[0-9]+]]:anygpr(p0) = G_FRAME_INDEX + ; CHECK: [[G_LOAD2:%[0-9]+]]:anygpr(s32) = G_LOAD [[G_F_I2]](p0) + ; CHECK: [[G_SUB1:%[0-9]+]]:anygpr(s32) = G_SUB [[G_LOAD1]], [[G_LOAD2]] + ; CHECK: $d0 = COPY [[G_SUB1]](s32) + ; CHECK: RTS implicit $d0 + %diff = sub i32 %x, %y + ret i32 %diff +}