LCOV - code coverage report
Current view: top level - lib/Target/AMDGPU/MCTargetDesc - AMDGPUAsmBackend.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 53 66 80.3 %
Date: 2018-07-13 00:08:38 Functions: 11 15 73.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===-- AMDGPUAsmBackend.cpp - AMDGPU Assembler Backend -------------------===//
       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             : /// \file
       9             : //===----------------------------------------------------------------------===//
      10             : 
      11             : #include "MCTargetDesc/AMDGPUFixupKinds.h"
      12             : #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
      13             : #include "llvm/ADT/StringRef.h"
      14             : #include "llvm/BinaryFormat/ELF.h"
      15             : #include "llvm/MC/MCAsmBackend.h"
      16             : #include "llvm/MC/MCAssembler.h"
      17             : #include "llvm/MC/MCContext.h"
      18             : #include "llvm/MC/MCFixupKindInfo.h"
      19             : #include "llvm/MC/MCObjectWriter.h"
      20             : #include "llvm/MC/MCValue.h"
      21             : #include "llvm/Support/TargetRegistry.h"
      22             : 
      23             : using namespace llvm;
      24             : 
      25             : namespace {
      26             : 
      27        2460 : class AMDGPUAsmBackend : public MCAsmBackend {
      28             : public:
      29        2470 :   AMDGPUAsmBackend(const Target &T) : MCAsmBackend(support::little) {}
      30             : 
      31           0 :   unsigned getNumFixupKinds() const override { return AMDGPU::NumTargetFixupKinds; };
      32             : 
      33             :   void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
      34             :                   const MCValue &Target, MutableArrayRef<char> Data,
      35             :                   uint64_t Value, bool IsResolved,
      36             :                   const MCSubtargetInfo *STI) const override;
      37           0 :   bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
      38             :                             const MCRelaxableFragment *DF,
      39             :                             const MCAsmLayout &Layout) const override {
      40           0 :     return false;
      41             :   }
      42           0 :   void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
      43             :                         MCInst &Res) const override {
      44           0 :     llvm_unreachable("Not implemented");
      45             :   }
      46        2450 :   bool mayNeedRelaxation(const MCInst &Inst,
      47             :                          const MCSubtargetInfo &STI) const override {
      48        2450 :     return false;
      49             :   }
      50             : 
      51             :   unsigned getMinimumNopSize() const override;
      52             :   bool writeNopData(raw_ostream &OS, uint64_t Count) const override;
      53             : 
      54             :   const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override;
      55             : };
      56             : 
      57             : } //End anonymous namespace
      58             : 
      59         210 : static unsigned getFixupKindNumBytes(unsigned Kind) {
      60         210 :   switch (Kind) {
      61             :   case AMDGPU::fixup_si_sopp_br:
      62             :     return 2;
      63           0 :   case FK_SecRel_1:
      64             :   case FK_Data_1:
      65           0 :     return 1;
      66             :   case FK_SecRel_2:
      67             :   case FK_Data_2:
      68             :     return 2;
      69         192 :   case FK_SecRel_4:
      70             :   case FK_Data_4:
      71             :   case FK_PCRel_4:
      72         192 :     return 4;
      73           0 :   case FK_SecRel_8:
      74             :   case FK_Data_8:
      75           0 :     return 8;
      76           0 :   default:
      77           0 :     llvm_unreachable("Unknown fixup kind!");
      78             :   }
      79             : }
      80             : 
      81         421 : static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
      82             :                                  MCContext *Ctx) {
      83         421 :   int64_t SignedValue = static_cast<int64_t>(Value);
      84             : 
      85         421 :   switch (static_cast<unsigned>(Fixup.getKind())) {
      86          20 :   case AMDGPU::fixup_si_sopp_br: {
      87          20 :     int64_t BrImm = (SignedValue - 4) / 4;
      88             : 
      89          40 :     if (Ctx && !isInt<16>(BrImm))
      90           1 :       Ctx->reportError(Fixup.getLoc(), "branch size exceeds simm16");
      91             : 
      92          20 :     return BrImm;
      93             :   }
      94             :   case FK_Data_1:
      95             :   case FK_Data_2:
      96             :   case FK_Data_4:
      97             :   case FK_Data_8:
      98             :   case FK_PCRel_4:
      99             :   case FK_SecRel_4:
     100             :     return Value;
     101           0 :   default:
     102           0 :     llvm_unreachable("unhandled fixup kind");
     103             :   }
     104             : }
     105             : 
     106         421 : void AMDGPUAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
     107             :                                   const MCValue &Target,
     108             :                                   MutableArrayRef<char> Data, uint64_t Value,
     109             :                                   bool IsResolved,
     110             :                                   const MCSubtargetInfo *STI) const {
     111         421 :   Value = adjustFixupValue(Fixup, Value, &Asm.getContext());
     112         421 :   if (!Value)
     113             :     return; // Doesn't change encoding.
     114             : 
     115         420 :   MCFixupKindInfo Info = getFixupKindInfo(Fixup.getKind());
     116             : 
     117             :   // Shift the value into position.
     118         210 :   Value <<= Info.TargetOffset;
     119             : 
     120         210 :   unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind());
     121         210 :   uint32_t Offset = Fixup.getOffset();
     122             :   assert(Offset + NumBytes <= Data.size() && "Invalid fixup offset!");
     123             : 
     124             :   // For each byte of the fragment that the fixup touches, mask in the bits from
     125             :   // the fixup value.
     126        1818 :   for (unsigned i = 0; i != NumBytes; ++i)
     127        1608 :     Data[Offset + i] |= static_cast<uint8_t>((Value >> (i * 8)) & 0xff);
     128             : }
     129             : 
     130        1266 : const MCFixupKindInfo &AMDGPUAsmBackend::getFixupKindInfo(
     131             :                                                        MCFixupKind Kind) const {
     132             :   const static MCFixupKindInfo Infos[AMDGPU::NumTargetFixupKinds] = {
     133             :     // name                   offset bits  flags
     134             :     { "fixup_si_sopp_br",     0,     16,   MCFixupKindInfo::FKF_IsPCRel },
     135             :   };
     136             : 
     137        1476 :   if (Kind < FirstTargetFixupKind)
     138        1342 :     return MCAsmBackend::getFixupKindInfo(Kind);
     139             : 
     140         134 :   return Infos[Kind - FirstTargetFixupKind];
     141             : }
     142             : 
     143         496 : unsigned AMDGPUAsmBackend::getMinimumNopSize() const {
     144         496 :   return 4;
     145             : }
     146             : 
     147         516 : bool AMDGPUAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const {
     148             :   // If the count is not 4-byte aligned, we must be writing data into the text
     149             :   // section (otherwise we have unaligned instructions, and thus have far
     150             :   // bigger problems), so just write zeros instead.
     151         516 :   OS.write_zeros(Count % 4);
     152             : 
     153             :   // We are properly aligned, so write NOPs as requested.
     154         516 :   Count /= 4;
     155             : 
     156             :   // FIXME: R600 support.
     157             :   // s_nop 0
     158             :   const uint32_t Encoded_S_NOP_0 = 0xbf800000;
     159             : 
     160       30090 :   for (uint64_t I = 0; I != Count; ++I)
     161       14787 :     support::endian::write<uint32_t>(OS, Encoded_S_NOP_0, Endian);
     162             : 
     163         516 :   return true;
     164             : }
     165             : 
     166             : //===----------------------------------------------------------------------===//
     167             : // ELFAMDGPUAsmBackend class
     168             : //===----------------------------------------------------------------------===//
     169             : 
     170             : namespace {
     171             : 
     172        4920 : class ELFAMDGPUAsmBackend : public AMDGPUAsmBackend {
     173             :   bool Is64Bit;
     174             :   bool HasRelocationAddend;
     175             :   uint8_t OSABI = ELF::ELFOSABI_NONE;
     176             : 
     177             : public:
     178        2470 :   ELFAMDGPUAsmBackend(const Target &T, const Triple &TT) :
     179        2470 :       AMDGPUAsmBackend(T), Is64Bit(TT.getArch() == Triple::amdgcn),
     180        4940 :       HasRelocationAddend(TT.getOS() == Triple::AMDHSA) {
     181        2470 :     switch (TT.getOS()) {
     182         350 :     case Triple::AMDHSA:
     183         350 :       OSABI = ELF::ELFOSABI_AMDGPU_HSA;
     184             :       break;
     185          53 :     case Triple::AMDPAL:
     186          53 :       OSABI = ELF::ELFOSABI_AMDGPU_PAL;
     187             :       break;
     188          17 :     case Triple::Mesa3D:
     189          17 :       OSABI = ELF::ELFOSABI_AMDGPU_MESA3D;
     190             :       break;
     191             :     default:
     192             :       break;
     193             :     }
     194        2470 :   }
     195             : 
     196             :   std::unique_ptr<MCObjectTargetWriter>
     197        2470 :   createObjectTargetWriter() const override {
     198        2470 :     return createAMDGPUELFObjectWriter(Is64Bit, OSABI, HasRelocationAddend);
     199             :   }
     200             : };
     201             : 
     202             : } // end anonymous namespace
     203             : 
     204        2470 : MCAsmBackend *llvm::createAMDGPUAsmBackend(const Target &T,
     205             :                                            const MCSubtargetInfo &STI,
     206             :                                            const MCRegisterInfo &MRI,
     207             :                                            const MCTargetOptions &Options) {
     208             :   // Use 64-bit ELF for amdgcn
     209        2470 :   return new ELFAMDGPUAsmBackend(T, STI.getTargetTriple());
     210             : }

Generated by: LCOV version 1.13