Home | History | Annotate | Download | only in MCTargetDesc
      1 //===-- BPFAsmBackend.cpp - BPF 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 //===----------------------------------------------------------------------===//
      9 
     10 #include "MCTargetDesc/BPFMCTargetDesc.h"
     11 #include "llvm/MC/MCAsmBackend.h"
     12 #include "llvm/MC/MCAssembler.h"
     13 #include "llvm/MC/MCDirectives.h"
     14 #include "llvm/MC/MCELFObjectWriter.h"
     15 #include "llvm/MC/MCFixupKindInfo.h"
     16 #include "llvm/MC/MCObjectWriter.h"
     17 #include "llvm/MC/MCSubtargetInfo.h"
     18 #include "llvm/MC/MCExpr.h"
     19 #include "llvm/MC/MCSymbol.h"
     20 #include "llvm/Support/ErrorHandling.h"
     21 #include "llvm/Support/raw_ostream.h"
     22 
     23 using namespace llvm;
     24 
     25 namespace {
     26 class BPFAsmBackend : public MCAsmBackend {
     27 public:
     28   BPFAsmBackend() : MCAsmBackend() {}
     29   ~BPFAsmBackend() override {}
     30 
     31   void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
     32                   uint64_t Value, bool IsPCRel) const override;
     33 
     34   MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override;
     35 
     36   // No instruction requires relaxation
     37   bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
     38                             const MCRelaxableFragment *DF,
     39                             const MCAsmLayout &Layout) const override {
     40     return false;
     41   }
     42 
     43   unsigned getNumFixupKinds() const override { return 1; }
     44 
     45   bool mayNeedRelaxation(const MCInst &Inst) const override { return false; }
     46 
     47   void relaxInstruction(const MCInst &Inst, MCInst &Res) const override {}
     48 
     49   bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override;
     50 };
     51 
     52 bool BPFAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
     53   if ((Count % 8) != 0)
     54     return false;
     55 
     56   for (uint64_t i = 0; i < Count; i += 8)
     57     OW->Write64(0x15000000);
     58 
     59   return true;
     60 }
     61 
     62 void BPFAsmBackend::applyFixup(const MCFixup &Fixup, char *Data,
     63                                unsigned DataSize, uint64_t Value,
     64                                bool IsPCRel) const {
     65 
     66   if (Fixup.getKind() == FK_SecRel_4 || Fixup.getKind() == FK_SecRel_8) {
     67     assert(Value == 0);
     68     return;
     69   }
     70   assert(Fixup.getKind() == FK_PCRel_2);
     71   *(uint16_t *)&Data[Fixup.getOffset() + 2] = (uint16_t)((Value - 8) / 8);
     72 }
     73 
     74 MCObjectWriter *BPFAsmBackend::createObjectWriter(raw_pwrite_stream &OS) const {
     75   return createBPFELFObjectWriter(OS, 0);
     76 }
     77 }
     78 
     79 MCAsmBackend *llvm::createBPFAsmBackend(const Target &T,
     80                                         const MCRegisterInfo &MRI, StringRef TT,
     81                                         StringRef CPU) {
     82   return new BPFAsmBackend();
     83 }
     84