xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===-- AMDGPUMCTargetDesc.cpp - AMDGPU Target Descriptions ---------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric /// \file
100b57cec5SDimitry Andric /// This file provides AMDGPU specific target descriptions.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #include "AMDGPUMCTargetDesc.h"
150b57cec5SDimitry Andric #include "AMDGPUELFStreamer.h"
160b57cec5SDimitry Andric #include "AMDGPUInstPrinter.h"
170b57cec5SDimitry Andric #include "AMDGPUMCAsmInfo.h"
180b57cec5SDimitry Andric #include "AMDGPUTargetStreamer.h"
19349cc55cSDimitry Andric #include "R600InstPrinter.h"
20349cc55cSDimitry Andric #include "R600MCTargetDesc.h"
210b57cec5SDimitry Andric #include "TargetInfo/AMDGPUTargetInfo.h"
2281ad6265SDimitry Andric #include "llvm/MC/LaneBitmask.h"
230b57cec5SDimitry Andric #include "llvm/MC/MCAsmBackend.h"
240b57cec5SDimitry Andric #include "llvm/MC/MCCodeEmitter.h"
25e8d8bef9SDimitry Andric #include "llvm/MC/MCELFStreamer.h"
26e8d8bef9SDimitry Andric #include "llvm/MC/MCInstPrinter.h"
270b57cec5SDimitry Andric #include "llvm/MC/MCInstrAnalysis.h"
28e8d8bef9SDimitry Andric #include "llvm/MC/MCInstrDesc.h"
290b57cec5SDimitry Andric #include "llvm/MC/MCInstrInfo.h"
300b57cec5SDimitry Andric #include "llvm/MC/MCObjectWriter.h"
3181ad6265SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
320b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h"
330b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
34349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h"
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric using namespace llvm;
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric #define GET_INSTRINFO_MC_DESC
39753f127fSDimitry Andric #define ENABLE_INSTR_PREDICATE_VERIFIER
400b57cec5SDimitry Andric #include "AMDGPUGenInstrInfo.inc"
410b57cec5SDimitry Andric 
420b57cec5SDimitry Andric #define GET_SUBTARGETINFO_MC_DESC
430b57cec5SDimitry Andric #include "AMDGPUGenSubtargetInfo.inc"
440b57cec5SDimitry Andric 
450b57cec5SDimitry Andric #define NoSchedModel NoSchedModelR600
460b57cec5SDimitry Andric #define GET_SUBTARGETINFO_MC_DESC
470b57cec5SDimitry Andric #include "R600GenSubtargetInfo.inc"
480b57cec5SDimitry Andric #undef NoSchedModelR600
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric #define GET_REGINFO_MC_DESC
510b57cec5SDimitry Andric #include "AMDGPUGenRegisterInfo.inc"
520b57cec5SDimitry Andric 
530b57cec5SDimitry Andric #define GET_REGINFO_MC_DESC
540b57cec5SDimitry Andric #include "R600GenRegisterInfo.inc"
550b57cec5SDimitry Andric 
560b57cec5SDimitry Andric static MCInstrInfo *createAMDGPUMCInstrInfo() {
570b57cec5SDimitry Andric   MCInstrInfo *X = new MCInstrInfo();
580b57cec5SDimitry Andric   InitAMDGPUMCInstrInfo(X);
590b57cec5SDimitry Andric   return X;
600b57cec5SDimitry Andric }
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric static MCRegisterInfo *createAMDGPUMCRegisterInfo(const Triple &TT) {
630b57cec5SDimitry Andric   MCRegisterInfo *X = new MCRegisterInfo();
640b57cec5SDimitry Andric   if (TT.getArch() == Triple::r600)
650b57cec5SDimitry Andric     InitR600MCRegisterInfo(X, 0);
660b57cec5SDimitry Andric   else
675ffd83dbSDimitry Andric     InitAMDGPUMCRegisterInfo(X, AMDGPU::PC_REG);
685ffd83dbSDimitry Andric   return X;
695ffd83dbSDimitry Andric }
705ffd83dbSDimitry Andric 
715ffd83dbSDimitry Andric MCRegisterInfo *llvm::createGCNMCRegisterInfo(AMDGPUDwarfFlavour DwarfFlavour) {
725ffd83dbSDimitry Andric   MCRegisterInfo *X = new MCRegisterInfo();
73*0fca6ea1SDimitry Andric   InitAMDGPUMCRegisterInfo(X, AMDGPU::PC_REG, DwarfFlavour, DwarfFlavour);
740b57cec5SDimitry Andric   return X;
750b57cec5SDimitry Andric }
760b57cec5SDimitry Andric 
770b57cec5SDimitry Andric static MCSubtargetInfo *
780b57cec5SDimitry Andric createAMDGPUMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) {
790b57cec5SDimitry Andric   if (TT.getArch() == Triple::r600)
80e8d8bef9SDimitry Andric     return createR600MCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, FS);
81e8d8bef9SDimitry Andric   return createAMDGPUMCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, FS);
820b57cec5SDimitry Andric }
830b57cec5SDimitry Andric 
840b57cec5SDimitry Andric static MCInstPrinter *createAMDGPUMCInstPrinter(const Triple &T,
850b57cec5SDimitry Andric                                                 unsigned SyntaxVariant,
860b57cec5SDimitry Andric                                                 const MCAsmInfo &MAI,
870b57cec5SDimitry Andric                                                 const MCInstrInfo &MII,
880b57cec5SDimitry Andric                                                 const MCRegisterInfo &MRI) {
890b57cec5SDimitry Andric   if (T.getArch() == Triple::r600)
900b57cec5SDimitry Andric     return new R600InstPrinter(MAI, MII, MRI);
910b57cec5SDimitry Andric   return new AMDGPUInstPrinter(MAI, MII, MRI);
920b57cec5SDimitry Andric }
930b57cec5SDimitry Andric 
94*0fca6ea1SDimitry Andric static MCTargetStreamer *
95*0fca6ea1SDimitry Andric createAMDGPUAsmTargetStreamer(MCStreamer &S, formatted_raw_ostream &OS,
96*0fca6ea1SDimitry Andric                               MCInstPrinter *InstPrint) {
970b57cec5SDimitry Andric   return new AMDGPUTargetAsmStreamer(S, OS);
980b57cec5SDimitry Andric }
990b57cec5SDimitry Andric 
1000b57cec5SDimitry Andric static MCTargetStreamer * createAMDGPUObjectTargetStreamer(
1010b57cec5SDimitry Andric                                                    MCStreamer &S,
1020b57cec5SDimitry Andric                                                    const MCSubtargetInfo &STI) {
1030b57cec5SDimitry Andric   return new AMDGPUTargetELFStreamer(S, STI);
1040b57cec5SDimitry Andric }
1050b57cec5SDimitry Andric 
106bdd1243dSDimitry Andric static MCTargetStreamer *createAMDGPUNullTargetStreamer(MCStreamer &S) {
107bdd1243dSDimitry Andric   return new AMDGPUTargetStreamer(S);
108bdd1243dSDimitry Andric }
109bdd1243dSDimitry Andric 
1100b57cec5SDimitry Andric static MCStreamer *createMCStreamer(const Triple &T, MCContext &Context,
1110b57cec5SDimitry Andric                                     std::unique_ptr<MCAsmBackend> &&MAB,
1120b57cec5SDimitry Andric                                     std::unique_ptr<MCObjectWriter> &&OW,
113*0fca6ea1SDimitry Andric                                     std::unique_ptr<MCCodeEmitter> &&Emitter) {
1140b57cec5SDimitry Andric   return createAMDGPUELFStreamer(T, Context, std::move(MAB), std::move(OW),
115*0fca6ea1SDimitry Andric                                  std::move(Emitter));
1160b57cec5SDimitry Andric }
1170b57cec5SDimitry Andric 
1180b57cec5SDimitry Andric namespace {
1190b57cec5SDimitry Andric 
1200b57cec5SDimitry Andric class AMDGPUMCInstrAnalysis : public MCInstrAnalysis {
1210b57cec5SDimitry Andric public:
1220b57cec5SDimitry Andric   explicit AMDGPUMCInstrAnalysis(const MCInstrInfo *Info)
1230b57cec5SDimitry Andric       : MCInstrAnalysis(Info) {}
1240b57cec5SDimitry Andric 
1250b57cec5SDimitry Andric   bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
1260b57cec5SDimitry Andric                       uint64_t &Target) const override {
1270b57cec5SDimitry Andric     if (Inst.getNumOperands() == 0 || !Inst.getOperand(0).isImm() ||
128bdd1243dSDimitry Andric         Info->get(Inst.getOpcode()).operands()[0].OperandType !=
1290b57cec5SDimitry Andric             MCOI::OPERAND_PCREL)
1300b57cec5SDimitry Andric       return false;
1310b57cec5SDimitry Andric 
1320b57cec5SDimitry Andric     int64_t Imm = Inst.getOperand(0).getImm();
1330b57cec5SDimitry Andric     // Our branches take a simm16, but we need two extra bits to account for
1340b57cec5SDimitry Andric     // the factor of 4.
1350b57cec5SDimitry Andric     APInt SignedOffset(18, Imm * 4, true);
1360b57cec5SDimitry Andric     Target = (SignedOffset.sext(64) + Addr + Size).getZExtValue();
1370b57cec5SDimitry Andric     return true;
1380b57cec5SDimitry Andric   }
1390b57cec5SDimitry Andric };
1400b57cec5SDimitry Andric 
1410b57cec5SDimitry Andric } // end anonymous namespace
1420b57cec5SDimitry Andric 
1430b57cec5SDimitry Andric static MCInstrAnalysis *createAMDGPUMCInstrAnalysis(const MCInstrInfo *Info) {
1440b57cec5SDimitry Andric   return new AMDGPUMCInstrAnalysis(Info);
1450b57cec5SDimitry Andric }
1460b57cec5SDimitry Andric 
147480093f4SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAMDGPUTargetMC() {
1480b57cec5SDimitry Andric 
1490b57cec5SDimitry Andric   TargetRegistry::RegisterMCInstrInfo(getTheGCNTarget(), createAMDGPUMCInstrInfo);
15006c3fb27SDimitry Andric   TargetRegistry::RegisterMCInstrInfo(getTheR600Target(),
15106c3fb27SDimitry Andric                                       createR600MCInstrInfo);
15206c3fb27SDimitry Andric   for (Target *T : {&getTheR600Target(), &getTheGCNTarget()}) {
1530b57cec5SDimitry Andric     RegisterMCAsmInfo<AMDGPUMCAsmInfo> X(*T);
1540b57cec5SDimitry Andric 
1550b57cec5SDimitry Andric     TargetRegistry::RegisterMCRegInfo(*T, createAMDGPUMCRegisterInfo);
1560b57cec5SDimitry Andric     TargetRegistry::RegisterMCSubtargetInfo(*T, createAMDGPUMCSubtargetInfo);
1570b57cec5SDimitry Andric     TargetRegistry::RegisterMCInstPrinter(*T, createAMDGPUMCInstPrinter);
1580b57cec5SDimitry Andric     TargetRegistry::RegisterMCInstrAnalysis(*T, createAMDGPUMCInstrAnalysis);
1590b57cec5SDimitry Andric     TargetRegistry::RegisterMCAsmBackend(*T, createAMDGPUAsmBackend);
1600b57cec5SDimitry Andric     TargetRegistry::RegisterELFStreamer(*T, createMCStreamer);
1610b57cec5SDimitry Andric   }
1620b57cec5SDimitry Andric 
1630b57cec5SDimitry Andric   // R600 specific registration
16406c3fb27SDimitry Andric   TargetRegistry::RegisterMCCodeEmitter(getTheR600Target(),
1650b57cec5SDimitry Andric                                         createR600MCCodeEmitter);
1660b57cec5SDimitry Andric   TargetRegistry::RegisterObjectTargetStreamer(
16706c3fb27SDimitry Andric       getTheR600Target(), createAMDGPUObjectTargetStreamer);
1680b57cec5SDimitry Andric 
1690b57cec5SDimitry Andric   // GCN specific registration
1700b57cec5SDimitry Andric   TargetRegistry::RegisterMCCodeEmitter(getTheGCNTarget(),
17106c3fb27SDimitry Andric                                         createAMDGPUMCCodeEmitter);
1720b57cec5SDimitry Andric 
1730b57cec5SDimitry Andric   TargetRegistry::RegisterAsmTargetStreamer(getTheGCNTarget(),
1740b57cec5SDimitry Andric                                             createAMDGPUAsmTargetStreamer);
1750b57cec5SDimitry Andric   TargetRegistry::RegisterObjectTargetStreamer(
1760b57cec5SDimitry Andric       getTheGCNTarget(), createAMDGPUObjectTargetStreamer);
177bdd1243dSDimitry Andric   TargetRegistry::RegisterNullTargetStreamer(getTheGCNTarget(),
178bdd1243dSDimitry Andric                                              createAMDGPUNullTargetStreamer);
1790b57cec5SDimitry Andric }
180