xref: /freebsd/contrib/llvm-project/llvm/lib/Target/M68k/M68kSubtarget.h (revision fe6060f10f634930ff71b7c50291ddc610da2475)
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