]>
Commit | Line | Data |
---|---|---|
223e47cc LB |
1 | //===-- PPCMCTargetDesc.cpp - PowerPC Target Descriptions -----------------===// |
2 | // | |
3 | // The LLVM Compiler Infrastructure | |
4 | // | |
5 | // This file is distributed under the University of Illinois Open Source | |
6 | // License. See LICENSE.TXT for details. | |
7 | // | |
8 | //===----------------------------------------------------------------------===// | |
9 | // | |
10 | // This file provides PowerPC specific target descriptions. | |
11 | // | |
12 | //===----------------------------------------------------------------------===// | |
13 | ||
14 | #include "PPCMCTargetDesc.h" | |
223e47cc | 15 | #include "InstPrinter/PPCInstPrinter.h" |
970d7e83 | 16 | #include "PPCMCAsmInfo.h" |
1a4d82fc | 17 | #include "PPCTargetStreamer.h" |
223e47cc | 18 | #include "llvm/MC/MCCodeGenInfo.h" |
1a4d82fc JJ |
19 | #include "llvm/MC/MCELF.h" |
20 | #include "llvm/MC/MCELFStreamer.h" | |
21 | #include "llvm/MC/MCExpr.h" | |
223e47cc LB |
22 | #include "llvm/MC/MCInstrInfo.h" |
23 | #include "llvm/MC/MCRegisterInfo.h" | |
24 | #include "llvm/MC/MCStreamer.h" | |
25 | #include "llvm/MC/MCSubtargetInfo.h" | |
1a4d82fc | 26 | #include "llvm/MC/MCSymbol.h" |
970d7e83 | 27 | #include "llvm/MC/MachineLocation.h" |
1a4d82fc | 28 | #include "llvm/Support/ELF.h" |
223e47cc | 29 | #include "llvm/Support/ErrorHandling.h" |
1a4d82fc | 30 | #include "llvm/Support/FormattedStream.h" |
223e47cc LB |
31 | #include "llvm/Support/TargetRegistry.h" |
32 | ||
1a4d82fc JJ |
33 | using namespace llvm; |
34 | ||
223e47cc LB |
35 | #define GET_INSTRINFO_MC_DESC |
36 | #include "PPCGenInstrInfo.inc" | |
37 | ||
38 | #define GET_SUBTARGETINFO_MC_DESC | |
39 | #include "PPCGenSubtargetInfo.inc" | |
40 | ||
41 | #define GET_REGINFO_MC_DESC | |
42 | #include "PPCGenRegisterInfo.inc" | |
43 | ||
1a4d82fc JJ |
44 | // Pin the vtable to this file. |
45 | PPCTargetStreamer::~PPCTargetStreamer() {} | |
46 | PPCTargetStreamer::PPCTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {} | |
223e47cc LB |
47 | |
48 | static MCInstrInfo *createPPCMCInstrInfo() { | |
49 | MCInstrInfo *X = new MCInstrInfo(); | |
50 | InitPPCMCInstrInfo(X); | |
51 | return X; | |
52 | } | |
53 | ||
54 | static MCRegisterInfo *createPPCMCRegisterInfo(StringRef TT) { | |
55 | Triple TheTriple(TT); | |
1a4d82fc JJ |
56 | bool isPPC64 = (TheTriple.getArch() == Triple::ppc64 || |
57 | TheTriple.getArch() == Triple::ppc64le); | |
223e47cc LB |
58 | unsigned Flavour = isPPC64 ? 0 : 1; |
59 | unsigned RA = isPPC64 ? PPC::LR8 : PPC::LR; | |
60 | ||
61 | MCRegisterInfo *X = new MCRegisterInfo(); | |
62 | InitPPCMCRegisterInfo(X, RA, Flavour, Flavour); | |
63 | return X; | |
64 | } | |
65 | ||
66 | static MCSubtargetInfo *createPPCMCSubtargetInfo(StringRef TT, StringRef CPU, | |
67 | StringRef FS) { | |
68 | MCSubtargetInfo *X = new MCSubtargetInfo(); | |
69 | InitPPCMCSubtargetInfo(X, TT, CPU, FS); | |
70 | return X; | |
71 | } | |
72 | ||
1a4d82fc | 73 | static MCAsmInfo *createPPCMCAsmInfo(const MCRegisterInfo &MRI, StringRef TT) { |
223e47cc | 74 | Triple TheTriple(TT); |
1a4d82fc JJ |
75 | bool isPPC64 = (TheTriple.getArch() == Triple::ppc64 || |
76 | TheTriple.getArch() == Triple::ppc64le); | |
223e47cc LB |
77 | |
78 | MCAsmInfo *MAI; | |
79 | if (TheTriple.isOSDarwin()) | |
1a4d82fc | 80 | MAI = new PPCMCAsmInfoDarwin(isPPC64, TheTriple); |
223e47cc | 81 | else |
1a4d82fc | 82 | MAI = new PPCELFMCAsmInfo(isPPC64, TheTriple); |
223e47cc LB |
83 | |
84 | // Initial state of the frame pointer is R1. | |
1a4d82fc JJ |
85 | unsigned Reg = isPPC64 ? PPC::X1 : PPC::R1; |
86 | MCCFIInstruction Inst = | |
87 | MCCFIInstruction::createDefCfa(nullptr, MRI.getDwarfRegNum(Reg, true), 0); | |
88 | MAI->addInitialFrameState(Inst); | |
223e47cc LB |
89 | |
90 | return MAI; | |
91 | } | |
92 | ||
93 | static MCCodeGenInfo *createPPCMCCodeGenInfo(StringRef TT, Reloc::Model RM, | |
94 | CodeModel::Model CM, | |
95 | CodeGenOpt::Level OL) { | |
96 | MCCodeGenInfo *X = new MCCodeGenInfo(); | |
97 | ||
98 | if (RM == Reloc::Default) { | |
99 | Triple T(TT); | |
100 | if (T.isOSDarwin()) | |
101 | RM = Reloc::DynamicNoPIC; | |
102 | else | |
103 | RM = Reloc::Static; | |
104 | } | |
970d7e83 LB |
105 | if (CM == CodeModel::Default) { |
106 | Triple T(TT); | |
1a4d82fc JJ |
107 | if (!T.isOSDarwin() && |
108 | (T.getArch() == Triple::ppc64 || T.getArch() == Triple::ppc64le)) | |
970d7e83 LB |
109 | CM = CodeModel::Medium; |
110 | } | |
223e47cc LB |
111 | X->InitMCCodeGenInfo(RM, CM, OL); |
112 | return X; | |
113 | } | |
114 | ||
1a4d82fc JJ |
115 | namespace { |
116 | class PPCTargetAsmStreamer : public PPCTargetStreamer { | |
117 | formatted_raw_ostream &OS; | |
118 | ||
119 | public: | |
120 | PPCTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS) | |
121 | : PPCTargetStreamer(S), OS(OS) {} | |
122 | void emitTCEntry(const MCSymbol &S) override { | |
123 | OS << "\t.tc "; | |
124 | OS << S.getName(); | |
125 | OS << "[TC],"; | |
126 | OS << S.getName(); | |
127 | OS << '\n'; | |
128 | } | |
129 | void emitMachine(StringRef CPU) override { | |
130 | OS << "\t.machine " << CPU << '\n'; | |
131 | } | |
132 | void emitAbiVersion(int AbiVersion) override { | |
133 | OS << "\t.abiversion " << AbiVersion << '\n'; | |
134 | } | |
135 | void emitLocalEntry(MCSymbol *S, const MCExpr *LocalOffset) override { | |
136 | OS << "\t.localentry\t" << *S << ", " << *LocalOffset << '\n'; | |
137 | } | |
138 | }; | |
139 | ||
140 | class PPCTargetELFStreamer : public PPCTargetStreamer { | |
141 | public: | |
142 | PPCTargetELFStreamer(MCStreamer &S) : PPCTargetStreamer(S) {} | |
143 | MCELFStreamer &getStreamer() { | |
144 | return static_cast<MCELFStreamer &>(Streamer); | |
145 | } | |
146 | void emitTCEntry(const MCSymbol &S) override { | |
147 | // Creates a R_PPC64_TOC relocation | |
148 | Streamer.EmitSymbolValue(&S, 8); | |
149 | } | |
150 | void emitMachine(StringRef CPU) override { | |
151 | // FIXME: Is there anything to do in here or does this directive only | |
152 | // limit the parser? | |
153 | } | |
154 | void emitAbiVersion(int AbiVersion) override { | |
155 | MCAssembler &MCA = getStreamer().getAssembler(); | |
156 | unsigned Flags = MCA.getELFHeaderEFlags(); | |
157 | Flags &= ~ELF::EF_PPC64_ABI; | |
158 | Flags |= (AbiVersion & ELF::EF_PPC64_ABI); | |
159 | MCA.setELFHeaderEFlags(Flags); | |
160 | } | |
161 | void emitLocalEntry(MCSymbol *S, const MCExpr *LocalOffset) override { | |
162 | MCAssembler &MCA = getStreamer().getAssembler(); | |
163 | MCSymbolData &Data = getStreamer().getOrCreateSymbolData(S); | |
164 | ||
165 | int64_t Res; | |
166 | if (!LocalOffset->EvaluateAsAbsolute(Res, MCA)) | |
167 | report_fatal_error(".localentry expression must be absolute."); | |
168 | ||
169 | unsigned Encoded = ELF::encodePPC64LocalEntryOffset(Res); | |
170 | if (Res != ELF::decodePPC64LocalEntryOffset(Encoded)) | |
171 | report_fatal_error(".localentry expression cannot be encoded."); | |
172 | ||
173 | // The "other" values are stored in the last 6 bits of the second byte. | |
174 | // The traditional defines for STO values assume the full byte and thus | |
175 | // the shift to pack it. | |
176 | unsigned Other = MCELF::getOther(Data) << 2; | |
177 | Other &= ~ELF::STO_PPC64_LOCAL_MASK; | |
178 | Other |= Encoded; | |
179 | MCELF::setOther(Data, Other >> 2); | |
180 | ||
181 | // For GAS compatibility, unless we already saw a .abiversion directive, | |
182 | // set e_flags to indicate ELFv2 ABI. | |
183 | unsigned Flags = MCA.getELFHeaderEFlags(); | |
184 | if ((Flags & ELF::EF_PPC64_ABI) == 0) | |
185 | MCA.setELFHeaderEFlags(Flags | 2); | |
186 | } | |
85aaf69f SL |
187 | void emitAssignment(MCSymbol *Symbol, const MCExpr *Value) override { |
188 | // When encoding an assignment to set symbol A to symbol B, also copy | |
189 | // the st_other bits encoding the local entry point offset. | |
190 | if (Value->getKind() != MCExpr::SymbolRef) | |
191 | return; | |
192 | const MCSymbol &RhsSym = | |
193 | static_cast<const MCSymbolRefExpr *>(Value)->getSymbol(); | |
194 | MCSymbolData &Data = getStreamer().getOrCreateSymbolData(&RhsSym); | |
195 | MCSymbolData &SymbolData = getStreamer().getOrCreateSymbolData(Symbol); | |
196 | // The "other" values are stored in the last 6 bits of the second byte. | |
197 | // The traditional defines for STO values assume the full byte and thus | |
198 | // the shift to pack it. | |
199 | unsigned Other = MCELF::getOther(SymbolData) << 2; | |
200 | Other &= ~ELF::STO_PPC64_LOCAL_MASK; | |
201 | Other |= (MCELF::getOther(Data) << 2) & ELF::STO_PPC64_LOCAL_MASK; | |
202 | MCELF::setOther(SymbolData, Other >> 2); | |
203 | } | |
1a4d82fc JJ |
204 | }; |
205 | ||
206 | class PPCTargetMachOStreamer : public PPCTargetStreamer { | |
207 | public: | |
208 | PPCTargetMachOStreamer(MCStreamer &S) : PPCTargetStreamer(S) {} | |
209 | void emitTCEntry(const MCSymbol &S) override { | |
210 | llvm_unreachable("Unknown pseudo-op: .tc"); | |
211 | } | |
212 | void emitMachine(StringRef CPU) override { | |
213 | // FIXME: We should update the CPUType, CPUSubType in the Object file if | |
214 | // the new values are different from the defaults. | |
215 | } | |
216 | void emitAbiVersion(int AbiVersion) override { | |
217 | llvm_unreachable("Unknown pseudo-op: .abiversion"); | |
218 | } | |
219 | void emitLocalEntry(MCSymbol *S, const MCExpr *LocalOffset) override { | |
220 | llvm_unreachable("Unknown pseudo-op: .localentry"); | |
221 | } | |
222 | }; | |
223 | } | |
224 | ||
223e47cc LB |
225 | // This is duplicated code. Refactor this. |
226 | static MCStreamer *createMCStreamer(const Target &T, StringRef TT, | |
227 | MCContext &Ctx, MCAsmBackend &MAB, | |
85aaf69f SL |
228 | raw_ostream &OS, MCCodeEmitter *Emitter, |
229 | const MCSubtargetInfo &STI, bool RelaxAll) { | |
1a4d82fc JJ |
230 | if (Triple(TT).isOSDarwin()) { |
231 | MCStreamer *S = createMachOStreamer(Ctx, MAB, OS, Emitter, RelaxAll); | |
232 | new PPCTargetMachOStreamer(*S); | |
233 | return S; | |
234 | } | |
223e47cc | 235 | |
85aaf69f | 236 | MCStreamer *S = createELFStreamer(Ctx, MAB, OS, Emitter, RelaxAll); |
1a4d82fc JJ |
237 | new PPCTargetELFStreamer(*S); |
238 | return S; | |
239 | } | |
240 | ||
241 | static MCStreamer * | |
242 | createMCAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, | |
243 | bool isVerboseAsm, bool useDwarfDirectory, | |
244 | MCInstPrinter *InstPrint, MCCodeEmitter *CE, | |
245 | MCAsmBackend *TAB, bool ShowInst) { | |
246 | ||
247 | MCStreamer *S = llvm::createAsmStreamer( | |
248 | Ctx, OS, isVerboseAsm, useDwarfDirectory, InstPrint, CE, TAB, ShowInst); | |
249 | new PPCTargetAsmStreamer(*S, OS); | |
250 | return S; | |
223e47cc LB |
251 | } |
252 | ||
253 | static MCInstPrinter *createPPCMCInstPrinter(const Target &T, | |
254 | unsigned SyntaxVariant, | |
255 | const MCAsmInfo &MAI, | |
256 | const MCInstrInfo &MII, | |
257 | const MCRegisterInfo &MRI, | |
258 | const MCSubtargetInfo &STI) { | |
1a4d82fc JJ |
259 | bool isDarwin = Triple(STI.getTargetTriple()).isOSDarwin(); |
260 | return new PPCInstPrinter(MAI, MII, MRI, isDarwin); | |
223e47cc LB |
261 | } |
262 | ||
263 | extern "C" void LLVMInitializePowerPCTargetMC() { | |
264 | // Register the MC asm info. | |
265 | RegisterMCAsmInfoFn C(ThePPC32Target, createPPCMCAsmInfo); | |
266 | RegisterMCAsmInfoFn D(ThePPC64Target, createPPCMCAsmInfo); | |
1a4d82fc | 267 | RegisterMCAsmInfoFn E(ThePPC64LETarget, createPPCMCAsmInfo); |
223e47cc LB |
268 | |
269 | // Register the MC codegen info. | |
270 | TargetRegistry::RegisterMCCodeGenInfo(ThePPC32Target, createPPCMCCodeGenInfo); | |
271 | TargetRegistry::RegisterMCCodeGenInfo(ThePPC64Target, createPPCMCCodeGenInfo); | |
1a4d82fc JJ |
272 | TargetRegistry::RegisterMCCodeGenInfo(ThePPC64LETarget, |
273 | createPPCMCCodeGenInfo); | |
223e47cc LB |
274 | |
275 | // Register the MC instruction info. | |
276 | TargetRegistry::RegisterMCInstrInfo(ThePPC32Target, createPPCMCInstrInfo); | |
277 | TargetRegistry::RegisterMCInstrInfo(ThePPC64Target, createPPCMCInstrInfo); | |
1a4d82fc JJ |
278 | TargetRegistry::RegisterMCInstrInfo(ThePPC64LETarget, |
279 | createPPCMCInstrInfo); | |
223e47cc LB |
280 | |
281 | // Register the MC register info. | |
282 | TargetRegistry::RegisterMCRegInfo(ThePPC32Target, createPPCMCRegisterInfo); | |
283 | TargetRegistry::RegisterMCRegInfo(ThePPC64Target, createPPCMCRegisterInfo); | |
1a4d82fc | 284 | TargetRegistry::RegisterMCRegInfo(ThePPC64LETarget, createPPCMCRegisterInfo); |
223e47cc LB |
285 | |
286 | // Register the MC subtarget info. | |
287 | TargetRegistry::RegisterMCSubtargetInfo(ThePPC32Target, | |
288 | createPPCMCSubtargetInfo); | |
289 | TargetRegistry::RegisterMCSubtargetInfo(ThePPC64Target, | |
290 | createPPCMCSubtargetInfo); | |
1a4d82fc JJ |
291 | TargetRegistry::RegisterMCSubtargetInfo(ThePPC64LETarget, |
292 | createPPCMCSubtargetInfo); | |
223e47cc LB |
293 | |
294 | // Register the MC Code Emitter | |
295 | TargetRegistry::RegisterMCCodeEmitter(ThePPC32Target, createPPCMCCodeEmitter); | |
296 | TargetRegistry::RegisterMCCodeEmitter(ThePPC64Target, createPPCMCCodeEmitter); | |
1a4d82fc JJ |
297 | TargetRegistry::RegisterMCCodeEmitter(ThePPC64LETarget, |
298 | createPPCMCCodeEmitter); | |
223e47cc LB |
299 | |
300 | // Register the asm backend. | |
301 | TargetRegistry::RegisterMCAsmBackend(ThePPC32Target, createPPCAsmBackend); | |
302 | TargetRegistry::RegisterMCAsmBackend(ThePPC64Target, createPPCAsmBackend); | |
1a4d82fc | 303 | TargetRegistry::RegisterMCAsmBackend(ThePPC64LETarget, createPPCAsmBackend); |
223e47cc LB |
304 | |
305 | // Register the object streamer. | |
306 | TargetRegistry::RegisterMCObjectStreamer(ThePPC32Target, createMCStreamer); | |
307 | TargetRegistry::RegisterMCObjectStreamer(ThePPC64Target, createMCStreamer); | |
1a4d82fc JJ |
308 | TargetRegistry::RegisterMCObjectStreamer(ThePPC64LETarget, createMCStreamer); |
309 | ||
310 | // Register the asm streamer. | |
311 | TargetRegistry::RegisterAsmStreamer(ThePPC32Target, createMCAsmStreamer); | |
312 | TargetRegistry::RegisterAsmStreamer(ThePPC64Target, createMCAsmStreamer); | |
313 | TargetRegistry::RegisterAsmStreamer(ThePPC64LETarget, createMCAsmStreamer); | |
223e47cc LB |
314 | |
315 | // Register the MCInstPrinter. | |
316 | TargetRegistry::RegisterMCInstPrinter(ThePPC32Target, createPPCMCInstPrinter); | |
317 | TargetRegistry::RegisterMCInstPrinter(ThePPC64Target, createPPCMCInstPrinter); | |
1a4d82fc JJ |
318 | TargetRegistry::RegisterMCInstPrinter(ThePPC64LETarget, |
319 | createPPCMCInstPrinter); | |
223e47cc | 320 | } |