//===-- M68kSubtarget.h - Define Subtarget for the M68k ---------*- 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 M68k specific subclass of TargetSubtargetInfo. /// //===----------------------------------------------------------------------===// #ifndef LLVM_LIB_TARGET_M68K_M68KSUBTARGET_H #define LLVM_LIB_TARGET_M68K_M68KSUBTARGET_H #include "M68kFrameLowering.h" #include "M68kISelLowering.h" #include "M68kInstrInfo.h" #include "llvm/CodeGen/GlobalISel/CallLowering.h" #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" #include "llvm/CodeGen/RegisterBankInfo.h" #include "llvm/CodeGen/SelectionDAGTargetInfo.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/IR/DataLayout.h" #include "llvm/MC/MCInstrItineraries.h" #include "llvm/Support/Alignment.h" #include #define GET_SUBTARGETINFO_HEADER #include "M68kGenSubtargetInfo.inc" extern bool M68kReserveGP; extern bool M68kNoCpload; namespace llvm { class StringRef; class M68kTargetMachine; class M68kSubtarget : public M68kGenSubtargetInfo { virtual void anchor(); protected: // These define which ISA is supported. Since each Motorola M68k ISA is // built on top of the previous one whenever an ISA is selected the previous // selected as well. enum SubtargetEnum { M00, M10, M20, M30, M40, M60 }; SubtargetEnum SubtargetKind = M00; enum FPKindEnum { M881, M882 }; std::optional FPUKind; std::bitset UserReservedRegister; InstrItineraryData InstrItins; /// Small section is used. bool UseSmallSection = true; const M68kTargetMachine &TM; SelectionDAGTargetInfo TSInfo; M68kInstrInfo InstrInfo; M68kFrameLowering FrameLowering; M68kTargetLowering TLInfo; /// The minimum alignment known to hold of the stack frame on /// entry to the function and which must be maintained by every function. unsigned stackAlignment = 8; Triple TargetTriple; public: /// This constructor initializes the data members to match that /// of the specified triple. M68kSubtarget(const Triple &TT, StringRef CPU, StringRef FS, const M68kTargetMachine &_TM); /// Parses features string setting specified subtarget options. Definition /// of function is auto generated by tblgen. void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS); bool atLeastM68000() const { return SubtargetKind >= M00; } bool atLeastM68010() const { return SubtargetKind >= M10; } bool atLeastM68020() const { return SubtargetKind >= M20; } bool atLeastM68030() const { return SubtargetKind >= M30; } bool atLeastM68040() const { return SubtargetKind >= M40; } bool atLeastM68060() const { return SubtargetKind >= M60; } /// Floating point support bool hasFPU() const { return FPUKind.has_value(); } bool atLeastM68881() const { return hasFPU() && *FPUKind >= M881; } bool atLeastM68882() const { return hasFPU() && *FPUKind >= M882; } bool useSmallSection() const { return UseSmallSection; } const Triple &getTargetTriple() const { return TargetTriple; } bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); } /// Return true if the subtarget allows calls to immediate address. bool isLegalToCallImmediateAddr() const; bool isPositionIndependent() const; bool isRegisterReservedByUser(Register R) const { assert(R < M68k::NUM_TARGET_REGS && "Register out of range"); return UserReservedRegister[R]; } /// Classify a global variable reference for the current subtarget according /// to how we should reference it in a non-pcrel context. unsigned char classifyLocalReference(const GlobalValue *GV) const; /// Classify a global variable reference for the current subtarget according /// to how we should reference it in a non-pcrel context. unsigned char classifyGlobalReference(const GlobalValue *GV, const Module &M) const; unsigned char classifyGlobalReference(const GlobalValue *GV) const; /// Classify a external variable reference for the current subtarget according /// to how we should reference it in a non-pcrel context. unsigned char classifyExternalReference(const Module &M) const; /// Classify a global function reference for the current subtarget. unsigned char classifyGlobalFunctionReference(const GlobalValue *GV, const Module &M) const; unsigned char classifyGlobalFunctionReference(const GlobalValue *GV) const override; /// Classify a blockaddress reference for the current subtarget according to /// how we should reference it in a non-pcrel context. unsigned char classifyBlockAddressReference() const; unsigned getJumpTableEncoding() const; /// TODO this must be controlled by options like -malign-int and -mshort Align getStackAlignment() const { return Align(stackAlignment); } /// getSlotSize - Stack slot size in bytes. unsigned getSlotSize() const { return 4; } M68kSubtarget &initializeSubtargetDependencies(StringRef CPU, Triple TT, StringRef FS, const M68kTargetMachine &TM); const SelectionDAGTargetInfo *getSelectionDAGInfo() const override { return &TSInfo; } const M68kInstrInfo *getInstrInfo() const override { return &InstrInfo; } const M68kFrameLowering *getFrameLowering() const override { return &FrameLowering; } const M68kRegisterInfo *getRegisterInfo() const override { return &InstrInfo.getRegisterInfo(); } const M68kTargetLowering *getTargetLowering() const override { return &TLInfo; } const InstrItineraryData *getInstrItineraryData() const override { return &InstrItins; } protected: // GlobalISel related APIs. std::unique_ptr CallLoweringInfo; std::unique_ptr InstSelector; std::unique_ptr Legalizer; std::unique_ptr RegBankInfo; public: const CallLowering *getCallLowering() const override; InstructionSelector *getInstructionSelector() const override; const LegalizerInfo *getLegalizerInfo() const override; const RegisterBankInfo *getRegBankInfo() const override; }; } // namespace llvm #endif // LLVM_LIB_TARGET_M68K_M68KSUBTARGET_H