104eeddc0SDimitry Andric //===-- M68kSubtarget.h - Define Subtarget for the M68k ---------*- C++ -*-===// 2fe6060f1SDimitry Andric // 3fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6fe6060f1SDimitry Andric // 7fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 8fe6060f1SDimitry Andric /// 9fe6060f1SDimitry Andric /// \file 10fe6060f1SDimitry Andric /// This file declares the M68k specific subclass of TargetSubtargetInfo. 11fe6060f1SDimitry Andric /// 12fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 13fe6060f1SDimitry Andric 1404eeddc0SDimitry Andric #ifndef LLVM_LIB_TARGET_M68K_M68KSUBTARGET_H 1504eeddc0SDimitry Andric #define LLVM_LIB_TARGET_M68K_M68KSUBTARGET_H 16fe6060f1SDimitry Andric 17fe6060f1SDimitry Andric #include "M68kFrameLowering.h" 18fe6060f1SDimitry Andric #include "M68kISelLowering.h" 19fe6060f1SDimitry Andric #include "M68kInstrInfo.h" 20fe6060f1SDimitry Andric 21fe6060f1SDimitry Andric #include "llvm/CodeGen/GlobalISel/CallLowering.h" 22fe6060f1SDimitry Andric #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" 23fe6060f1SDimitry Andric #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" 2481ad6265SDimitry Andric #include "llvm/CodeGen/RegisterBankInfo.h" 25fe6060f1SDimitry Andric #include "llvm/CodeGen/SelectionDAGTargetInfo.h" 26fe6060f1SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h" 27fe6060f1SDimitry Andric #include "llvm/IR/DataLayout.h" 28fe6060f1SDimitry Andric #include "llvm/MC/MCInstrItineraries.h" 29fe6060f1SDimitry Andric #include "llvm/Support/Alignment.h" 30fe6060f1SDimitry Andric 31fe6060f1SDimitry Andric #include <string> 32fe6060f1SDimitry Andric 33fe6060f1SDimitry Andric #define GET_SUBTARGETINFO_HEADER 34fe6060f1SDimitry Andric #include "M68kGenSubtargetInfo.inc" 35fe6060f1SDimitry Andric 36fe6060f1SDimitry Andric extern bool M68kReserveGP; 37fe6060f1SDimitry Andric extern bool M68kNoCpload; 38fe6060f1SDimitry Andric 39fe6060f1SDimitry Andric namespace llvm { 40fe6060f1SDimitry Andric class StringRef; 41fe6060f1SDimitry Andric 42fe6060f1SDimitry Andric class M68kTargetMachine; 43fe6060f1SDimitry Andric 44fe6060f1SDimitry Andric class M68kSubtarget : public M68kGenSubtargetInfo { 45fe6060f1SDimitry Andric virtual void anchor(); 46fe6060f1SDimitry Andric 47fe6060f1SDimitry Andric protected: 48fe6060f1SDimitry Andric // These define which ISA is supported. Since each Motorola M68k ISA is 49fe6060f1SDimitry Andric // built on top of the previous one whenever an ISA is selected the previous 50fe6060f1SDimitry Andric // selected as well. 51fe6060f1SDimitry Andric enum SubtargetEnum { M00, M10, M20, M30, M40, M60 }; 52fe6060f1SDimitry Andric SubtargetEnum SubtargetKind = M00; 53fe6060f1SDimitry Andric 54*06c3fb27SDimitry Andric enum FPKindEnum { M881, M882 }; 55*06c3fb27SDimitry Andric std::optional<FPKindEnum> FPUKind; 56*06c3fb27SDimitry Andric 57bdd1243dSDimitry Andric std::bitset<M68k::NUM_TARGET_REGS> UserReservedRegister; 58fe6060f1SDimitry Andric 59fe6060f1SDimitry Andric InstrItineraryData InstrItins; 60fe6060f1SDimitry Andric 61fe6060f1SDimitry Andric /// Small section is used. 62fe6060f1SDimitry Andric bool UseSmallSection = true; 63fe6060f1SDimitry Andric 64fe6060f1SDimitry Andric const M68kTargetMachine &TM; 65fe6060f1SDimitry Andric 66fe6060f1SDimitry Andric SelectionDAGTargetInfo TSInfo; 67fe6060f1SDimitry Andric M68kInstrInfo InstrInfo; 68fe6060f1SDimitry Andric M68kFrameLowering FrameLowering; 69fe6060f1SDimitry Andric M68kTargetLowering TLInfo; 70fe6060f1SDimitry Andric 71fe6060f1SDimitry Andric /// The minimum alignment known to hold of the stack frame on 72fe6060f1SDimitry Andric /// entry to the function and which must be maintained by every function. 73fe6060f1SDimitry Andric unsigned stackAlignment = 8; 74fe6060f1SDimitry Andric 75fe6060f1SDimitry Andric Triple TargetTriple; 76fe6060f1SDimitry Andric 77fe6060f1SDimitry Andric public: 78fe6060f1SDimitry Andric /// This constructor initializes the data members to match that 79fe6060f1SDimitry Andric /// of the specified triple. 80fe6060f1SDimitry Andric M68kSubtarget(const Triple &TT, StringRef CPU, StringRef FS, 81fe6060f1SDimitry Andric const M68kTargetMachine &_TM); 82fe6060f1SDimitry Andric 83fe6060f1SDimitry Andric /// Parses features string setting specified subtarget options. Definition 84fe6060f1SDimitry Andric /// of function is auto generated by tblgen. 85fe6060f1SDimitry Andric void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS); 86fe6060f1SDimitry Andric atLeastM68000()87fe6060f1SDimitry Andric bool atLeastM68000() const { return SubtargetKind >= M00; } atLeastM68010()88fe6060f1SDimitry Andric bool atLeastM68010() const { return SubtargetKind >= M10; } atLeastM68020()89fe6060f1SDimitry Andric bool atLeastM68020() const { return SubtargetKind >= M20; } atLeastM68030()90fe6060f1SDimitry Andric bool atLeastM68030() const { return SubtargetKind >= M30; } atLeastM68040()91fe6060f1SDimitry Andric bool atLeastM68040() const { return SubtargetKind >= M40; } atLeastM68060()92fe6060f1SDimitry Andric bool atLeastM68060() const { return SubtargetKind >= M60; } 93fe6060f1SDimitry Andric 94*06c3fb27SDimitry Andric /// Floating point support hasFPU()95*06c3fb27SDimitry Andric bool hasFPU() const { return FPUKind.has_value(); } atLeastM68881()96*06c3fb27SDimitry Andric bool atLeastM68881() const { return hasFPU() && *FPUKind >= M881; } atLeastM68882()97*06c3fb27SDimitry Andric bool atLeastM68882() const { return hasFPU() && *FPUKind >= M882; } 98fe6060f1SDimitry Andric useSmallSection()99*06c3fb27SDimitry Andric bool useSmallSection() const { return UseSmallSection; } 100fe6060f1SDimitry Andric getTargetTriple()101fe6060f1SDimitry Andric const Triple &getTargetTriple() const { return TargetTriple; } 102fe6060f1SDimitry Andric isTargetELF()103fe6060f1SDimitry Andric bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); } 104fe6060f1SDimitry Andric 105fe6060f1SDimitry Andric /// Return true if the subtarget allows calls to immediate address. 106fe6060f1SDimitry Andric bool isLegalToCallImmediateAddr() const; 107fe6060f1SDimitry Andric 108fe6060f1SDimitry Andric bool isPositionIndependent() const; 109fe6060f1SDimitry Andric isRegisterReservedByUser(Register R)110fe6060f1SDimitry Andric bool isRegisterReservedByUser(Register R) const { 111fe6060f1SDimitry Andric assert(R < M68k::NUM_TARGET_REGS && "Register out of range"); 112fe6060f1SDimitry Andric return UserReservedRegister[R]; 113fe6060f1SDimitry Andric } 114fe6060f1SDimitry Andric 115fe6060f1SDimitry Andric /// Classify a global variable reference for the current subtarget according 116fe6060f1SDimitry Andric /// to how we should reference it in a non-pcrel context. 117fe6060f1SDimitry Andric unsigned char classifyLocalReference(const GlobalValue *GV) const; 118fe6060f1SDimitry Andric 119fe6060f1SDimitry Andric /// Classify a global variable reference for the current subtarget according 120fe6060f1SDimitry Andric /// to how we should reference it in a non-pcrel context. 121fe6060f1SDimitry Andric unsigned char classifyGlobalReference(const GlobalValue *GV, 122fe6060f1SDimitry Andric const Module &M) const; 123fe6060f1SDimitry Andric unsigned char classifyGlobalReference(const GlobalValue *GV) const; 124fe6060f1SDimitry Andric 125fe6060f1SDimitry Andric /// Classify a external variable reference for the current subtarget according 126fe6060f1SDimitry Andric /// to how we should reference it in a non-pcrel context. 127fe6060f1SDimitry Andric unsigned char classifyExternalReference(const Module &M) const; 128fe6060f1SDimitry Andric 129fe6060f1SDimitry Andric /// Classify a global function reference for the current subtarget. 130fe6060f1SDimitry Andric unsigned char classifyGlobalFunctionReference(const GlobalValue *GV, 131fe6060f1SDimitry Andric const Module &M) const; 132bdd1243dSDimitry Andric unsigned char 133bdd1243dSDimitry Andric classifyGlobalFunctionReference(const GlobalValue *GV) const override; 134fe6060f1SDimitry Andric 135fe6060f1SDimitry Andric /// Classify a blockaddress reference for the current subtarget according to 136fe6060f1SDimitry Andric /// how we should reference it in a non-pcrel context. 137fe6060f1SDimitry Andric unsigned char classifyBlockAddressReference() const; 138fe6060f1SDimitry Andric 139fe6060f1SDimitry Andric unsigned getJumpTableEncoding() const; 140fe6060f1SDimitry Andric 141fe6060f1SDimitry Andric /// TODO this must be controlled by options like -malign-int and -mshort getStackAlignment()142fe6060f1SDimitry Andric Align getStackAlignment() const { return Align(stackAlignment); } 143fe6060f1SDimitry Andric 144fe6060f1SDimitry Andric /// getSlotSize - Stack slot size in bytes. getSlotSize()145fe6060f1SDimitry Andric unsigned getSlotSize() const { return 4; } 146fe6060f1SDimitry Andric 147fe6060f1SDimitry Andric M68kSubtarget &initializeSubtargetDependencies(StringRef CPU, Triple TT, 148fe6060f1SDimitry Andric StringRef FS, 149fe6060f1SDimitry Andric const M68kTargetMachine &TM); 150fe6060f1SDimitry Andric getSelectionDAGInfo()151fe6060f1SDimitry Andric const SelectionDAGTargetInfo *getSelectionDAGInfo() const override { 152fe6060f1SDimitry Andric return &TSInfo; 153fe6060f1SDimitry Andric } 154fe6060f1SDimitry Andric getInstrInfo()155fe6060f1SDimitry Andric const M68kInstrInfo *getInstrInfo() const override { return &InstrInfo; } 156fe6060f1SDimitry Andric getFrameLowering()157fe6060f1SDimitry Andric const M68kFrameLowering *getFrameLowering() const override { 158fe6060f1SDimitry Andric return &FrameLowering; 159fe6060f1SDimitry Andric } 160fe6060f1SDimitry Andric getRegisterInfo()161fe6060f1SDimitry Andric const M68kRegisterInfo *getRegisterInfo() const override { 162fe6060f1SDimitry Andric return &InstrInfo.getRegisterInfo(); 163fe6060f1SDimitry Andric } 164fe6060f1SDimitry Andric getTargetLowering()165fe6060f1SDimitry Andric const M68kTargetLowering *getTargetLowering() const override { 166fe6060f1SDimitry Andric return &TLInfo; 167fe6060f1SDimitry Andric } 168fe6060f1SDimitry Andric getInstrItineraryData()169fe6060f1SDimitry Andric const InstrItineraryData *getInstrItineraryData() const override { 170fe6060f1SDimitry Andric return &InstrItins; 171fe6060f1SDimitry Andric } 172fe6060f1SDimitry Andric 173fe6060f1SDimitry Andric protected: 174fe6060f1SDimitry Andric // GlobalISel related APIs. 175fe6060f1SDimitry Andric std::unique_ptr<CallLowering> CallLoweringInfo; 176fe6060f1SDimitry Andric std::unique_ptr<InstructionSelector> InstSelector; 177fe6060f1SDimitry Andric std::unique_ptr<LegalizerInfo> Legalizer; 178fe6060f1SDimitry Andric std::unique_ptr<RegisterBankInfo> RegBankInfo; 179fe6060f1SDimitry Andric 180fe6060f1SDimitry Andric public: 181fe6060f1SDimitry Andric const CallLowering *getCallLowering() const override; 182fe6060f1SDimitry Andric InstructionSelector *getInstructionSelector() const override; 183fe6060f1SDimitry Andric const LegalizerInfo *getLegalizerInfo() const override; 184fe6060f1SDimitry Andric const RegisterBankInfo *getRegBankInfo() const override; 185fe6060f1SDimitry Andric }; 186fe6060f1SDimitry Andric } // namespace llvm 187fe6060f1SDimitry Andric 18804eeddc0SDimitry Andric #endif // LLVM_LIB_TARGET_M68K_M68KSUBTARGET_H 189