1//===-- ARMTargetMachine.h - Define TargetMachine for ARM -------*- 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// This file declares the ARM specific subclass of TargetMachine.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_LIB_TARGET_ARM_ARMTARGETMACHINE_H
14#define LLVM_LIB_TARGET_ARM_ARMTARGETMACHINE_H
15
16#include "ARMSubtarget.h"
17#include "llvm/ADT/StringMap.h"
18#include "llvm/ADT/StringRef.h"
19#include "llvm/Analysis/TargetTransformInfo.h"
20#include "llvm/CodeGen/CodeGenTargetMachineImpl.h"
21#include "llvm/Support/CodeGen.h"
22#include "llvm/Target/TargetMachine.h"
23#include "llvm/TargetParser/ARMTargetParser.h"
24#include <memory>
25#include <optional>
26
27namespace llvm {
28
29class ARMBaseTargetMachine : public CodeGenTargetMachineImpl {
30public:
31 ARM::ARMABI TargetABI;
32
33protected:
34 std::unique_ptr<TargetLoweringObjectFile> TLOF;
35 bool isLittle;
36 mutable StringMap<std::unique_ptr<ARMSubtarget>> SubtargetMap;
37
38 /// Reset internal state.
39 void reset() override;
40
41public:
42 ARMBaseTargetMachine(const Target &T, const Triple &TT, StringRef CPU,
43 StringRef FS, const TargetOptions &Options,
44 std::optional<Reloc::Model> RM,
45 std::optional<CodeModel::Model> CM, CodeGenOptLevel OL);
46 ~ARMBaseTargetMachine() override;
47
48 const ARMSubtarget *getSubtargetImpl(const Function &F) const override;
49 // DO NOT IMPLEMENT: There is no such thing as a valid default subtarget,
50 // subtargets are per-function entities based on the target-specific
51 // attributes of each function.
52 const ARMSubtarget *getSubtargetImpl() const = delete;
53 bool isLittleEndian() const { return isLittle; }
54
55 TargetTransformInfo getTargetTransformInfo(const Function &F) const override;
56
57 // Pass Pipeline Configuration
58 TargetPassConfig *createPassConfig(PassManagerBase &PM) override;
59
60 void registerPassBuilderCallbacks(PassBuilder &PB) override;
61
62 TargetLoweringObjectFile *getObjFileLowering() const override {
63 return TLOF.get();
64 }
65
66 bool isAPCS_ABI() const {
67 assert(TargetABI != ARM::ARM_ABI_UNKNOWN);
68 return TargetABI == ARM::ARM_ABI_APCS;
69 }
70
71 bool isAAPCS_ABI() const {
72 assert(TargetABI != ARM::ARM_ABI_UNKNOWN);
73 return TargetABI == ARM::ARM_ABI_AAPCS || TargetABI == ARM::ARM_ABI_AAPCS16;
74 }
75
76 bool isAAPCS16_ABI() const {
77 assert(TargetABI != ARM::ARM_ABI_UNKNOWN);
78 return TargetABI == ARM::ARM_ABI_AAPCS16;
79 }
80
81 bool isTargetHardFloat() const {
82 return TargetTriple.getEnvironment() == Triple::GNUEABIHF ||
83 TargetTriple.getEnvironment() == Triple::GNUEABIHFT64 ||
84 TargetTriple.getEnvironment() == Triple::MuslEABIHF ||
85 TargetTriple.getEnvironment() == Triple::EABIHF ||
86 (TargetTriple.isOSBinFormatMachO() &&
87 TargetTriple.getSubArch() == Triple::ARMSubArch_v7em) ||
88 TargetTriple.isOSWindows() || TargetABI == ARM::ARM_ABI_AAPCS16;
89 }
90
91 bool targetSchedulesPostRAScheduling() const override { return true; };
92
93 MachineFunctionInfo *
94 createMachineFunctionInfo(BumpPtrAllocator &Allocator, const Function &F,
95 const TargetSubtargetInfo *STI) const override;
96
97 /// Returns true if a cast between SrcAS and DestAS is a noop.
98 bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const override {
99 // Addrspacecasts are always noops.
100 return true;
101 }
102
103 bool isGVIndirectSymbol(const GlobalValue *GV) const {
104 if (!shouldAssumeDSOLocal(GV))
105 return true;
106
107 // 32 bit macho has no relocation for a-b if a is undefined, even if b is in
108 // the section that is being relocated. This means we have to use o load
109 // even for GVs that are known to be local to the dso.
110 if (getTargetTriple().isOSBinFormatMachO() && isPositionIndependent() &&
111 (GV->isDeclarationForLinker() || GV->hasCommonLinkage()))
112 return true;
113
114 // In ELF PIC mode, weak symbols referenced via the constant pool use a
115 // PC-relative expression (e.g. .long xxx-(.LPC+8)) that the assembler
116 // eagerly resolves when both the symbol and label are in the same section.
117 // This prevents the linker from overriding a weak definition with a
118 // non-weak one. Use GOT indirection for weak symbols to avoid this.
119 if (getTargetTriple().isOSBinFormatELF() && isPositionIndependent() &&
120 GV->isWeakForLinker())
121 return true;
122
123 return false;
124 }
125
126 yaml::MachineFunctionInfo *createDefaultFuncInfoYAML() const override;
127 yaml::MachineFunctionInfo *
128 convertFuncInfoToYAML(const MachineFunction &MF) const override;
129 bool parseMachineFunctionInfo(const yaml::MachineFunctionInfo &,
130 PerFunctionMIParsingState &PFS,
131 SMDiagnostic &Error,
132 SMRange &SourceRange) const override;
133 ScheduleDAGInstrs *
134 createMachineScheduler(MachineSchedContext *C) const override;
135 ScheduleDAGInstrs *
136 createPostMachineScheduler(MachineSchedContext *C) const override;
137};
138
139/// ARM/Thumb little endian target machine.
140///
141class ARMLETargetMachine : public ARMBaseTargetMachine {
142public:
143 ARMLETargetMachine(const Target &T, const Triple &TT, StringRef CPU,
144 StringRef FS, const TargetOptions &Options,
145 std::optional<Reloc::Model> RM,
146 std::optional<CodeModel::Model> CM, CodeGenOptLevel OL,
147 bool JIT);
148};
149
150/// ARM/Thumb big endian target machine.
151///
152class ARMBETargetMachine : public ARMBaseTargetMachine {
153public:
154 ARMBETargetMachine(const Target &T, const Triple &TT, StringRef CPU,
155 StringRef FS, const TargetOptions &Options,
156 std::optional<Reloc::Model> RM,
157 std::optional<CodeModel::Model> CM, CodeGenOptLevel OL,
158 bool JIT);
159};
160
161} // end namespace llvm
162
163#endif // LLVM_LIB_TARGET_ARM_ARMTARGETMACHINE_H
164