LLVM API Documentation
00001 //===-- AMDGPUAsmBackend.cpp - AMDGPU Assembler Backend -------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 /// \file 00009 //===----------------------------------------------------------------------===// 00010 00011 #include "MCTargetDesc/AMDGPUMCTargetDesc.h" 00012 #include "MCTargetDesc/AMDGPUFixupKinds.h" 00013 #include "llvm/ADT/StringRef.h" 00014 #include "llvm/MC/MCAsmBackend.h" 00015 #include "llvm/MC/MCAssembler.h" 00016 #include "llvm/MC/MCFixupKindInfo.h" 00017 #include "llvm/MC/MCObjectWriter.h" 00018 #include "llvm/MC/MCValue.h" 00019 #include "llvm/Support/TargetRegistry.h" 00020 00021 using namespace llvm; 00022 00023 namespace { 00024 00025 class AMDGPUMCObjectWriter : public MCObjectWriter { 00026 public: 00027 AMDGPUMCObjectWriter(raw_ostream &OS) : MCObjectWriter(OS, true) { } 00028 void ExecutePostLayoutBinding(MCAssembler &Asm, 00029 const MCAsmLayout &Layout) override { 00030 //XXX: Implement if necessary. 00031 } 00032 void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, 00033 const MCFragment *Fragment, const MCFixup &Fixup, 00034 MCValue Target, bool &IsPCRel, 00035 uint64_t &FixedValue) override { 00036 assert(!"Not implemented"); 00037 } 00038 00039 void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout) override; 00040 00041 }; 00042 00043 class AMDGPUAsmBackend : public MCAsmBackend { 00044 public: 00045 AMDGPUAsmBackend(const Target &T) 00046 : MCAsmBackend() {} 00047 00048 unsigned getNumFixupKinds() const override { return AMDGPU::NumTargetFixupKinds; }; 00049 void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, 00050 uint64_t Value, bool IsPCRel) const override; 00051 bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, 00052 const MCRelaxableFragment *DF, 00053 const MCAsmLayout &Layout) const override { 00054 return false; 00055 } 00056 void relaxInstruction(const MCInst &Inst, MCInst &Res) const override { 00057 assert(!"Not implemented"); 00058 } 00059 bool mayNeedRelaxation(const MCInst &Inst) const override { return false; } 00060 bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override { 00061 return true; 00062 } 00063 00064 const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override; 00065 }; 00066 00067 } //End anonymous namespace 00068 00069 void AMDGPUMCObjectWriter::WriteObject(MCAssembler &Asm, 00070 const MCAsmLayout &Layout) { 00071 for (MCAssembler::iterator I = Asm.begin(), E = Asm.end(); I != E; ++I) { 00072 Asm.writeSectionData(I, Layout); 00073 } 00074 } 00075 00076 void AMDGPUAsmBackend::applyFixup(const MCFixup &Fixup, char *Data, 00077 unsigned DataSize, uint64_t Value, 00078 bool IsPCRel) const { 00079 00080 switch ((unsigned)Fixup.getKind()) { 00081 default: llvm_unreachable("Unknown fixup kind"); 00082 case AMDGPU::fixup_si_sopp_br: { 00083 uint16_t *Dst = (uint16_t*)(Data + Fixup.getOffset()); 00084 *Dst = (Value - 4) / 4; 00085 break; 00086 } 00087 00088 case AMDGPU::fixup_si_rodata: { 00089 uint32_t *Dst = (uint32_t*)(Data + Fixup.getOffset()); 00090 *Dst = Value; 00091 break; 00092 } 00093 00094 case AMDGPU::fixup_si_end_of_text: { 00095 uint32_t *Dst = (uint32_t*)(Data + Fixup.getOffset()); 00096 // The value points to the last instruction in the text section, so we 00097 // need to add 4 bytes to get to the start of the constants. 00098 *Dst = Value + 4; 00099 break; 00100 } 00101 } 00102 } 00103 00104 const MCFixupKindInfo &AMDGPUAsmBackend::getFixupKindInfo( 00105 MCFixupKind Kind) const { 00106 const static MCFixupKindInfo Infos[AMDGPU::NumTargetFixupKinds] = { 00107 // name offset bits flags 00108 { "fixup_si_sopp_br", 0, 16, MCFixupKindInfo::FKF_IsPCRel }, 00109 { "fixup_si_rodata", 0, 32, 0 }, 00110 { "fixup_si_end_of_text", 0, 32, MCFixupKindInfo::FKF_IsPCRel } 00111 }; 00112 00113 if (Kind < FirstTargetFixupKind) 00114 return MCAsmBackend::getFixupKindInfo(Kind); 00115 00116 return Infos[Kind - FirstTargetFixupKind]; 00117 } 00118 00119 //===----------------------------------------------------------------------===// 00120 // ELFAMDGPUAsmBackend class 00121 //===----------------------------------------------------------------------===// 00122 00123 namespace { 00124 00125 class ELFAMDGPUAsmBackend : public AMDGPUAsmBackend { 00126 public: 00127 ELFAMDGPUAsmBackend(const Target &T) : AMDGPUAsmBackend(T) { } 00128 00129 MCObjectWriter *createObjectWriter(raw_ostream &OS) const override { 00130 return createAMDGPUELFObjectWriter(OS); 00131 } 00132 }; 00133 00134 } // end anonymous namespace 00135 00136 MCAsmBackend *llvm::createAMDGPUAsmBackend(const Target &T, 00137 const MCRegisterInfo &MRI, 00138 StringRef TT, 00139 StringRef CPU) { 00140 return new ELFAMDGPUAsmBackend(T); 00141 }