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