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