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