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