ArrayRef<ArrayRef<Register>> ArgRegs, Register SwiftErrorVReg,
std::function<unsigned()> GetCalleeReg) const;
+ /// For targets which want to use big-endian can enable it with
+ /// enableBigEndian() hook
+ virtual bool enableBigEndian() const { return false; }
+
/// For targets which support the "returned" parameter attribute, returns
/// true if the given type is a valid one to use with "returned".
virtual bool isTypeIsValidForThisReturn(EVT Ty) const { return false; }
assert(PendingPHIs.empty() && "stale PHIs");
- if (!DL->isLittleEndian()) {
+ // Targets which want to use big endian can enable it using
+ // enableBigEndian()
+ if (!DL->isLittleEndian() && !CLI->enableBigEndian()) {
// Currently we don't properly handle big endian code.
OptimizationRemarkMissed R("gisel-irtranslator", "GISelFailure",
F.getSubprogram(), &F.getEntryBlock());
set(LLVM_TARGET_DEFINITIONS M68k.td)
+tablegen(LLVM M68kGenGlobalISel.inc -gen-global-isel)
tablegen(LLVM M68kGenRegisterInfo.inc -gen-register-info)
+tablegen(LLVM M68kGenRegisterBank.inc -gen-register-bank)
tablegen(LLVM M68kGenInstrInfo.inc -gen-instr-info)
tablegen(LLVM M68kGenSubtargetInfo.inc -gen-subtarget)
tablegen(LLVM M68kGenMCCodeBeads.inc -gen-code-beads)
add_public_tablegen_target(M68kCommonTableGen)
add_llvm_target(M68kCodeGen
+ GlSel/M68kCallLowering.cpp
+ GlSel/M68kInstructionSelector.cpp
+ GlSel/M68kLegalizerInfo.cpp
+ GlSel/M68kRegisterBankInfo.cpp
M68kAsmPrinter.cpp
M68kCollapseMOVEMPass.cpp
M68kExpandPseudo.cpp
AsmPrinter
CodeGen
Core
+ GlobalISel
MC
SelectionDAG
Support
--- /dev/null
+//===-- M68kCallLowering.cpp - Call lowering -------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file
+/// This file implements the lowering of LLVM calls to machine code calls for
+/// GlobalISel.
+//
+//===----------------------------------------------------------------------===//
+
+#include "M68kCallLowering.h"
+#include "M68kISelLowering.h"
+#include "M68kInstrInfo.h"
+#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
+using namespace llvm;
+
+M68kCallLowering::M68kCallLowering(const M68kTargetLowering &TLI)
+ : CallLowering(&TLI) {}
+
+bool M68kCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
+ const Value *Val, ArrayRef<Register> VRegs,
+ FunctionLoweringInfo &FLI,
+ Register SwiftErrorVReg) const {
+
+ if (Val)
+ return false;
+ MIRBuilder.buildInstr(M68k::RTS);
+ return true;
+}
+
+bool M68kCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
+ const Function &F,
+ ArrayRef<ArrayRef<Register>> VRegs,
+ FunctionLoweringInfo &FLI) const {
+
+ if (F.arg_empty())
+ return true;
+
+ return false;
+}
+
+bool M68kCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
+ CallLoweringInfo &Info) const {
+ return false;
+}
+
+bool M68kCallLowering::enableBigEndian() const { return true; }
--- /dev/null
+//===-- M68kCallLowering.h - Call lowering -------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file
+/// This file implements the lowering of LLVM calls to machine code calls for
+/// GlobalISel.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_M68K_GLSEL_M68KCALLLOWERING_H
+#define LLVM_LIB_TARGET_M68K_GLSEL_M68KCALLLOWERING_H
+
+#include "llvm/CodeGen/CallingConvLower.h"
+#include "llvm/CodeGen/GlobalISel/CallLowering.h"
+#include "llvm/CodeGen/ValueTypes.h"
+
+namespace llvm {
+
+class M68kTargetLowering;
+
+class M68kCallLowering : public CallLowering {
+ // TODO: We are only supporting return instruction with no value at this time
+ // point
+
+public:
+ M68kCallLowering(const M68kTargetLowering &TLI);
+
+ bool lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val,
+ ArrayRef<Register> VRegs, FunctionLoweringInfo &FLI,
+ Register SwiftErrorVReg) const override;
+
+ bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F,
+ ArrayRef<ArrayRef<Register>> VRegs,
+ FunctionLoweringInfo &FLI) const override;
+
+ bool lowerCall(MachineIRBuilder &MIRBuilder,
+ CallLoweringInfo &Info) const override;
+
+ bool enableBigEndian() const override;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_LIB_TARGET_M68K_GLSEL_M68KCALLLOWERING_H
--- /dev/null
+//===- M68kInstructionSelector.cpp ------------------------------*- C++ -*-===//
+//===----------------------------------------------------------------------===//
+/// \file
+/// This file implements the targeting of the InstructionSelector class for
+/// M68k.
+/// \todo This should be generated by TableGen.
+//===----------------------------------------------------------------------===//
+
+#include "M68kRegisterBankInfo.h"
+#include "M68kSubtarget.h"
+#include "M68kTargetMachine.h"
+#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
+#include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h"
+#include "llvm/Support/Debug.h"
+
+#define DEBUG_TYPE "m68k-isel"
+
+using namespace llvm;
+
+#define GET_GLOBALISEL_PREDICATE_BITSET
+#include "M68kGenGlobalISel.inc"
+#undef GET_GLOBALISEL_PREDICATE_BITSET
+
+namespace {
+
+class M68kInstructionSelector : public InstructionSelector {
+public:
+ M68kInstructionSelector(const M68kTargetMachine &TM, const M68kSubtarget &STI,
+ const M68kRegisterBankInfo &RBI);
+
+ bool select(MachineInstr &I) override;
+ static const char *getName() { return DEBUG_TYPE; }
+
+private:
+ bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
+
+ const M68kTargetMachine &TM;
+ const M68kInstrInfo &TII;
+ const M68kRegisterInfo &TRI;
+ const M68kRegisterBankInfo &RBI;
+
+#define GET_GLOBALISEL_PREDICATES_DECL
+#include "M68kGenGlobalISel.inc"
+#undef GET_GLOBALISEL_PREDICATES_DECL
+
+#define GET_GLOBALISEL_TEMPORARIES_DECL
+#include "M68kGenGlobalISel.inc"
+#undef GET_GLOBALISEL_TEMPORARIES_DECL
+};
+
+} // end anonymous namespace
+
+#define GET_GLOBALISEL_IMPL
+#include "M68kGenGlobalISel.inc"
+#undef GET_GLOBALISEL_IMPL
+
+M68kInstructionSelector::M68kInstructionSelector(
+ const M68kTargetMachine &TM, const M68kSubtarget &STI,
+ const M68kRegisterBankInfo &RBI)
+ : InstructionSelector(), TM(TM), TII(*STI.getInstrInfo()),
+ TRI(*STI.getRegisterInfo()), RBI(RBI),
+
+#define GET_GLOBALISEL_PREDICATES_INIT
+#include "M68kGenGlobalISel.inc"
+#undef GET_GLOBALISEL_PREDICATES_INIT
+#define GET_GLOBALISEL_TEMPORARIES_INIT
+#include "M68kGenGlobalISel.inc"
+#undef GET_GLOBALISEL_TEMPORARIES_INIT
+{
+}
+
+bool M68kInstructionSelector::select(MachineInstr &I) {
+ // Certain non-generic instructions also need some special handling.
+ if (!isPreISelGenericOpcode(I.getOpcode()))
+ return true;
+
+ if (selectImpl(I, *CoverageInfo))
+ return true;
+
+ return false;
+}
+
+namespace llvm {
+InstructionSelector *
+createM68kInstructionSelector(const M68kTargetMachine &TM,
+ const M68kSubtarget &Subtarget,
+ const M68kRegisterBankInfo &RBI) {
+ return new M68kInstructionSelector(TM, Subtarget, RBI);
+}
+} // end namespace llvm
--- /dev/null
+//===-- M68kLegalizerInfo.cpp ----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// This file implements the targeting of the Machinelegalizer class for M68k.
+//===----------------------------------------------------------------------===//
+
+#include "M68kLegalizerInfo.h"
+#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
+#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
+#include "llvm/CodeGen/TargetOpcodes.h"
+#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Type.h"
+
+using namespace llvm;
+
+M68kLegalizerInfo::M68kLegalizerInfo(const M68kSubtarget &ST) {
+ getLegacyLegalizerInfo().computeTables();
+}
--- /dev/null
+//===- M68kLegalizerInfo --------------------------------------*- C++ -*-==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// This file declares the targeting of the MachineLegalizer class for
+/// M68k.
+/// \todo This should be generated by TableGen.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_M68K_GLSEL_M68KLEGALIZERINFO_H
+#define LLVM_LIB_TARGET_M68K_GLSEL_M68KLEGALIZERINFO_H
+
+#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
+
+namespace llvm {
+
+class M68kSubtarget;
+
+/// This struct provides the information for the target register banks.
+struct M68kLegalizerInfo : public LegalizerInfo {
+public:
+ M68kLegalizerInfo(const M68kSubtarget &ST);
+};
+} // end namespace llvm
+#endif // LLVM_LIB_TARGET_M68K_GLSEL_M68KLEGALIZERINFO_H
--- /dev/null
+//===-- M68kRegisterBankInfo.cpp -------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// This file implements the targeting of the RegisterBankInfo class for M68k.
+/// \todo This should be generated by TableGen.
+//===----------------------------------------------------------------------===//
+
+#include "M68kRegisterBankInfo.h"
+#include "MCTargetDesc/M68kMCTargetDesc.h"
+#include "llvm/CodeGen/GlobalISel/RegisterBank.h"
+#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
+
+#define GET_TARGET_REGBANK_IMPL
+#include "M68kGenRegisterBank.inc"
+#undef GET_TARGET_REGBANK_IMPL
+
+using namespace llvm;
+
+M68kRegisterBankInfo::M68kRegisterBankInfo(const TargetRegisterInfo &TRI)
+ : M68kGenRegisterBankInfo() {}
--- /dev/null
+//===-- M68kRegisterBankInfo.h ---------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// This file declares the targeting of the RegisterBankInfo class for M68k.
+/// \todo This should be generated by TableGen.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_M68K_GLSEL_M68KREGISTERBANKINFO_H
+#define LLVM_LIB_TARGET_M68K_GLSEL_M68KREGISTERBANKINFO_H
+
+#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
+
+#define GET_REGBANK_DECLARATIONS
+#include "M68kGenRegisterBank.inc"
+#undef GET_REGBANK_DECLARATIONS
+
+namespace llvm {
+
+class TargetRegisterInfo;
+
+class M68kGenRegisterBankInfo : public RegisterBankInfo {
+protected:
+#define GET_TARGET_REGBANK_CLASS
+#include "M68kGenRegisterBank.inc"
+#undef GET_TARGET_REGBANK_CLASS
+};
+
+/// This class provides the information for the target register banks.
+class M68kRegisterBankInfo final : public M68kGenRegisterBankInfo {
+public:
+ M68kRegisterBankInfo(const TargetRegisterInfo &TRI);
+};
+} // end namespace llvm
+#endif
--- /dev/null
+//===-- M68kRegisterBanks.td - Describe the M68k Banks -------*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Define the M68k register banks used for GlobalISel.
+///
+//===----------------------------------------------------------------------===//
+
+/// General Purpose Registers. Here we define a register bank with name AnyGPR
+def GPRRegBank : RegisterBank<"AnyGPR", [DR8]>;
namespace llvm {
class FunctionPass;
+class InstructionSelector;
+class M68kRegisterBankInfo;
+class M68kSubtarget;
class M68kTargetMachine;
/// This pass converts a legalized DAG into a M68k-specific DAG, ready for
/// so that all possible MOVEs are present.
FunctionPass *createM68kConvertMOVToMOVMPass();
+InstructionSelector *
+createM68kInstructionSelector(const M68kTargetMachine &, const M68kSubtarget &,
+ const M68kRegisterBankInfo &);
+
} // namespace llvm
#endif
//===----------------------------------------------------------------------===//
include "M68kRegisterInfo.td"
+include "GlSel/M68kRegisterBanks.td"
//===----------------------------------------------------------------------===//
// Instruction Descriptions
//===----------------------------------------------------------------------===//
#include "M68kSubtarget.h"
+#include "GlSel/M68kCallLowering.h"
+#include "GlSel/M68kLegalizerInfo.h"
+#include "GlSel/M68kRegisterBankInfo.cpp"
#include "M68k.h"
#include "M68kMachineFunction.h"
UserReservedRegister(M68k::NUM_TARGET_REGS), TM(TM), TSInfo(),
InstrInfo(initializeSubtargetDependencies(CPU, TT, FS, TM)),
FrameLowering(*this, this->getStackAlignment()), TLInfo(TM, *this),
- TargetTriple(TT) {}
+ TargetTriple(TT) {
+ CallLoweringInfo.reset(new M68kCallLowering(*getTargetLowering()));
+ Legalizer.reset(new M68kLegalizerInfo(*this));
+
+ auto *RBI = new M68kRegisterBankInfo(*getRegisterInfo());
+ RegBankInfo.reset(RBI);
+ InstSelector.reset(createM68kInstructionSelector(TM, *this, *RBI));
+}
+
+const CallLowering *M68kSubtarget::getCallLowering() const {
+ return CallLoweringInfo.get();
+}
+
+InstructionSelector *M68kSubtarget::getInstructionSelector() const {
+ return InstSelector.get();
+}
+
+const LegalizerInfo *M68kSubtarget::getLegalizerInfo() const {
+ return Legalizer.get();
+}
+
+const RegisterBankInfo *M68kSubtarget::getRegBankInfo() const {
+ return RegBankInfo.get();
+}
bool M68kSubtarget::isPositionIndependent() const {
return TM.isPositionIndependent();
#include "M68kInstrInfo.h"
#include "llvm/ADT/BitVector.h"
+#include "llvm/CodeGen/GlobalISel/CallLowering.h"
+#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
+#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
+#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/DataLayout.h"
const InstrItineraryData *getInstrItineraryData() const override {
return &InstrItins;
}
+
+protected:
+ // GlobalISel related APIs.
+ std::unique_ptr<CallLowering> CallLoweringInfo;
+ std::unique_ptr<InstructionSelector> InstSelector;
+ std::unique_ptr<LegalizerInfo> Legalizer;
+ std::unique_ptr<RegisterBankInfo> RegBankInfo;
+
+public:
+ const CallLowering *getCallLowering() const override;
+ InstructionSelector *getInstructionSelector() const override;
+ const LegalizerInfo *getLegalizerInfo() const override;
+ const RegisterBankInfo *getRegBankInfo() const override;
};
} // namespace llvm
#include "M68kTargetMachine.h"
#include "M68k.h"
-#include "TargetInfo/M68kTargetInfo.h"
-
#include "M68kSubtarget.h"
#include "M68kTargetObjectFile.h"
-
+#include "TargetInfo/M68kTargetInfo.h"
+#include "llvm/CodeGen/GlobalISel/IRTranslator.h"
+#include "llvm/CodeGen/GlobalISel/InstructionSelect.h"
+#include "llvm/CodeGen/GlobalISel/Legalizer.h"
+#include "llvm/CodeGen/GlobalISel/RegBankSelect.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/IR/LegacyPassManager.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/PassRegistry.h"
#include "llvm/Support/TargetRegistry.h"
#include <memory>
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeM68kTarget() {
RegisterTargetMachine<M68kTargetMachine> X(getTheM68kTarget());
+ auto *PR = PassRegistry::getPassRegistry();
+ initializeGlobalISel(*PR);
}
namespace {
const M68kSubtarget &getM68kSubtarget() const {
return *getM68kTargetMachine().getSubtargetImpl();
}
-
+ bool addIRTranslator() override;
+ bool addLegalizeMachineIR() override;
+ bool addRegBankSelect() override;
+ bool addGlobalInstructionSelect() override;
bool addInstSelector() override;
void addPreSched2() override;
void addPreEmitPass() override;
return false;
}
+bool M68kPassConfig::addIRTranslator() {
+ addPass(new IRTranslator());
+ return false;
+}
+
+bool M68kPassConfig::addLegalizeMachineIR() {
+ addPass(new Legalizer());
+ return false;
+}
+
+bool M68kPassConfig::addRegBankSelect() {
+ addPass(new RegBankSelect());
+ return false;
+}
+
+bool M68kPassConfig::addGlobalInstructionSelect() {
+ addPass(new InstructionSelect());
+ return false;
+}
+
void M68kPassConfig::addPreSched2() { addPass(createM68kExpandPseudoPass()); }
void M68kPassConfig::addPreEmitPass() {
--- /dev/null
+; RUN: llc -mtriple=m68k -global-isel -stop-after=irtranslator < %s | FileCheck %s
+
+; CHECK: name: noArgRetVoid
+; CHECK: RTS
+define void @noArgRetVoid() {
+ ret void
+}