1 | //===-- AMDGPUMCTargetDesc.cpp - AMDGPU Target Descriptions ---------------===// |
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 provides AMDGPU specific target descriptions. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #include "AMDGPUMCTargetDesc.h" |
15 | #include "AMDGPUELFStreamer.h" |
16 | #include "AMDGPUInstPrinter.h" |
17 | #include "AMDGPUMCAsmInfo.h" |
18 | #include "AMDGPUTargetStreamer.h" |
19 | #include "R600InstPrinter.h" |
20 | #include "R600MCTargetDesc.h" |
21 | #include "TargetInfo/AMDGPUTargetInfo.h" |
22 | #include "llvm/MC/LaneBitmask.h" |
23 | #include "llvm/MC/MCAsmBackend.h" |
24 | #include "llvm/MC/MCCodeEmitter.h" |
25 | #include "llvm/MC/MCELFStreamer.h" |
26 | #include "llvm/MC/MCInstPrinter.h" |
27 | #include "llvm/MC/MCInstrAnalysis.h" |
28 | #include "llvm/MC/MCInstrDesc.h" |
29 | #include "llvm/MC/MCInstrInfo.h" |
30 | #include "llvm/MC/MCObjectWriter.h" |
31 | #include "llvm/MC/MCRegisterInfo.h" |
32 | #include "llvm/MC/MCStreamer.h" |
33 | #include "llvm/MC/MCSubtargetInfo.h" |
34 | #include "llvm/MC/TargetRegistry.h" |
35 | |
36 | using namespace llvm; |
37 | |
38 | #define GET_INSTRINFO_MC_DESC |
39 | #define ENABLE_INSTR_PREDICATE_VERIFIER |
40 | #include "AMDGPUGenInstrInfo.inc" |
41 | |
42 | #define GET_SUBTARGETINFO_MC_DESC |
43 | #include "AMDGPUGenSubtargetInfo.inc" |
44 | |
45 | #define NoSchedModel NoSchedModelR600 |
46 | #define GET_SUBTARGETINFO_MC_DESC |
47 | #include "R600GenSubtargetInfo.inc" |
48 | #undef NoSchedModelR600 |
49 | |
50 | #define GET_REGINFO_MC_DESC |
51 | #include "AMDGPUGenRegisterInfo.inc" |
52 | |
53 | #define GET_REGINFO_MC_DESC |
54 | #include "R600GenRegisterInfo.inc" |
55 | |
56 | static MCInstrInfo *createAMDGPUMCInstrInfo() { |
57 | MCInstrInfo *X = new MCInstrInfo(); |
58 | InitAMDGPUMCInstrInfo(X); |
59 | return X; |
60 | } |
61 | |
62 | static MCRegisterInfo *createAMDGPUMCRegisterInfo(const Triple &TT) { |
63 | MCRegisterInfo *X = new MCRegisterInfo(); |
64 | if (TT.getArch() == Triple::r600) |
65 | InitR600MCRegisterInfo(X, 0); |
66 | else |
67 | InitAMDGPUMCRegisterInfo(X, AMDGPU::PC_REG); |
68 | return X; |
69 | } |
70 | |
71 | MCRegisterInfo *llvm::createGCNMCRegisterInfo(AMDGPUDwarfFlavour DwarfFlavour) { |
72 | MCRegisterInfo *X = new MCRegisterInfo(); |
73 | InitAMDGPUMCRegisterInfo(X, AMDGPU::PC_REG, DwarfFlavour, DwarfFlavour); |
74 | return X; |
75 | } |
76 | |
77 | static MCSubtargetInfo * |
78 | createAMDGPUMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) { |
79 | if (TT.getArch() == Triple::r600) |
80 | return createR600MCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, FS); |
81 | return createAMDGPUMCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, FS); |
82 | } |
83 | |
84 | static MCInstPrinter *createAMDGPUMCInstPrinter(const Triple &T, |
85 | unsigned SyntaxVariant, |
86 | const MCAsmInfo &MAI, |
87 | const MCInstrInfo &MII, |
88 | const MCRegisterInfo &MRI) { |
89 | if (T.getArch() == Triple::r600) |
90 | return new R600InstPrinter(MAI, MII, MRI); |
91 | else |
92 | return new AMDGPUInstPrinter(MAI, MII, MRI); |
93 | } |
94 | |
95 | static MCTargetStreamer *createAMDGPUAsmTargetStreamer(MCStreamer &S, |
96 | formatted_raw_ostream &OS, |
97 | MCInstPrinter *InstPrint, |
98 | bool isVerboseAsm) { |
99 | return new AMDGPUTargetAsmStreamer(S, OS); |
100 | } |
101 | |
102 | static MCTargetStreamer * createAMDGPUObjectTargetStreamer( |
103 | MCStreamer &S, |
104 | const MCSubtargetInfo &STI) { |
105 | return new AMDGPUTargetELFStreamer(S, STI); |
106 | } |
107 | |
108 | static MCTargetStreamer *createAMDGPUNullTargetStreamer(MCStreamer &S) { |
109 | return new AMDGPUTargetStreamer(S); |
110 | } |
111 | |
112 | static MCStreamer *createMCStreamer(const Triple &T, MCContext &Context, |
113 | std::unique_ptr<MCAsmBackend> &&MAB, |
114 | std::unique_ptr<MCObjectWriter> &&OW, |
115 | std::unique_ptr<MCCodeEmitter> &&Emitter, |
116 | bool RelaxAll) { |
117 | return createAMDGPUELFStreamer(T, Context, MAB: std::move(MAB), OW: std::move(OW), |
118 | Emitter: std::move(Emitter), RelaxAll); |
119 | } |
120 | |
121 | namespace { |
122 | |
123 | class AMDGPUMCInstrAnalysis : public MCInstrAnalysis { |
124 | public: |
125 | explicit AMDGPUMCInstrAnalysis(const MCInstrInfo *Info) |
126 | : MCInstrAnalysis(Info) {} |
127 | |
128 | bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size, |
129 | uint64_t &Target) const override { |
130 | if (Inst.getNumOperands() == 0 || !Inst.getOperand(i: 0).isImm() || |
131 | Info->get(Opcode: Inst.getOpcode()).operands()[0].OperandType != |
132 | MCOI::OPERAND_PCREL) |
133 | return false; |
134 | |
135 | int64_t Imm = Inst.getOperand(i: 0).getImm(); |
136 | // Our branches take a simm16, but we need two extra bits to account for |
137 | // the factor of 4. |
138 | APInt SignedOffset(18, Imm * 4, true); |
139 | Target = (SignedOffset.sext(width: 64) + Addr + Size).getZExtValue(); |
140 | return true; |
141 | } |
142 | }; |
143 | |
144 | } // end anonymous namespace |
145 | |
146 | static MCInstrAnalysis *createAMDGPUMCInstrAnalysis(const MCInstrInfo *Info) { |
147 | return new AMDGPUMCInstrAnalysis(Info); |
148 | } |
149 | |
150 | extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAMDGPUTargetMC() { |
151 | |
152 | TargetRegistry::RegisterMCInstrInfo(T&: getTheGCNTarget(), Fn: createAMDGPUMCInstrInfo); |
153 | TargetRegistry::RegisterMCInstrInfo(T&: getTheR600Target(), |
154 | Fn: createR600MCInstrInfo); |
155 | for (Target *T : {&getTheR600Target(), &getTheGCNTarget()}) { |
156 | RegisterMCAsmInfo<AMDGPUMCAsmInfo> X(*T); |
157 | |
158 | TargetRegistry::RegisterMCRegInfo(T&: *T, Fn: createAMDGPUMCRegisterInfo); |
159 | TargetRegistry::RegisterMCSubtargetInfo(T&: *T, Fn: createAMDGPUMCSubtargetInfo); |
160 | TargetRegistry::RegisterMCInstPrinter(T&: *T, Fn: createAMDGPUMCInstPrinter); |
161 | TargetRegistry::RegisterMCInstrAnalysis(T&: *T, Fn: createAMDGPUMCInstrAnalysis); |
162 | TargetRegistry::RegisterMCAsmBackend(T&: *T, Fn: createAMDGPUAsmBackend); |
163 | TargetRegistry::RegisterELFStreamer(T&: *T, Fn: createMCStreamer); |
164 | } |
165 | |
166 | // R600 specific registration |
167 | TargetRegistry::RegisterMCCodeEmitter(T&: getTheR600Target(), |
168 | Fn: createR600MCCodeEmitter); |
169 | TargetRegistry::RegisterObjectTargetStreamer( |
170 | T&: getTheR600Target(), Fn: createAMDGPUObjectTargetStreamer); |
171 | |
172 | // GCN specific registration |
173 | TargetRegistry::RegisterMCCodeEmitter(T&: getTheGCNTarget(), |
174 | Fn: createAMDGPUMCCodeEmitter); |
175 | |
176 | TargetRegistry::RegisterAsmTargetStreamer(T&: getTheGCNTarget(), |
177 | Fn: createAMDGPUAsmTargetStreamer); |
178 | TargetRegistry::RegisterObjectTargetStreamer( |
179 | T&: getTheGCNTarget(), Fn: createAMDGPUObjectTargetStreamer); |
180 | TargetRegistry::RegisterNullTargetStreamer(T&: getTheGCNTarget(), |
181 | Fn: createAMDGPUNullTargetStreamer); |
182 | } |
183 | |