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