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