xref: /aosp_15_r20/external/llvm/lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- BPFAsmBackend.cpp - BPF Assembler Backend -------------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker 
10*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/BPFMCTargetDesc.h"
11*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCAsmBackend.h"
12*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCAssembler.h"
13*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCDirectives.h"
14*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCELFObjectWriter.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCFixupKindInfo.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCObjectWriter.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSubtargetInfo.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCExpr.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSymbol.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorHandling.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
22*9880d681SAndroid Build Coastguard Worker 
23*9880d681SAndroid Build Coastguard Worker using namespace llvm;
24*9880d681SAndroid Build Coastguard Worker 
25*9880d681SAndroid Build Coastguard Worker namespace {
26*9880d681SAndroid Build Coastguard Worker class BPFAsmBackend : public MCAsmBackend {
27*9880d681SAndroid Build Coastguard Worker public:
28*9880d681SAndroid Build Coastguard Worker   bool IsLittleEndian;
29*9880d681SAndroid Build Coastguard Worker 
BPFAsmBackend(bool IsLittleEndian)30*9880d681SAndroid Build Coastguard Worker   BPFAsmBackend(bool IsLittleEndian)
31*9880d681SAndroid Build Coastguard Worker     : MCAsmBackend(), IsLittleEndian(IsLittleEndian) {}
~BPFAsmBackend()32*9880d681SAndroid Build Coastguard Worker   ~BPFAsmBackend() override {}
33*9880d681SAndroid Build Coastguard Worker 
34*9880d681SAndroid Build Coastguard Worker   void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
35*9880d681SAndroid Build Coastguard Worker                   uint64_t Value, bool IsPCRel) const override;
36*9880d681SAndroid Build Coastguard Worker 
37*9880d681SAndroid Build Coastguard Worker   MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override;
38*9880d681SAndroid Build Coastguard Worker 
39*9880d681SAndroid Build Coastguard Worker   // No instruction requires relaxation
fixupNeedsRelaxation(const MCFixup & Fixup,uint64_t Value,const MCRelaxableFragment * DF,const MCAsmLayout & Layout) const40*9880d681SAndroid Build Coastguard Worker   bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
41*9880d681SAndroid Build Coastguard Worker                             const MCRelaxableFragment *DF,
42*9880d681SAndroid Build Coastguard Worker                             const MCAsmLayout &Layout) const override {
43*9880d681SAndroid Build Coastguard Worker     return false;
44*9880d681SAndroid Build Coastguard Worker   }
45*9880d681SAndroid Build Coastguard Worker 
getNumFixupKinds() const46*9880d681SAndroid Build Coastguard Worker   unsigned getNumFixupKinds() const override { return 1; }
47*9880d681SAndroid Build Coastguard Worker 
mayNeedRelaxation(const MCInst & Inst) const48*9880d681SAndroid Build Coastguard Worker   bool mayNeedRelaxation(const MCInst &Inst) const override { return false; }
49*9880d681SAndroid Build Coastguard Worker 
relaxInstruction(const MCInst & Inst,const MCSubtargetInfo & STI,MCInst & Res) const50*9880d681SAndroid Build Coastguard Worker   void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
51*9880d681SAndroid Build Coastguard Worker                         MCInst &Res) const override {}
52*9880d681SAndroid Build Coastguard Worker 
53*9880d681SAndroid Build Coastguard Worker   bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override;
54*9880d681SAndroid Build Coastguard Worker };
55*9880d681SAndroid Build Coastguard Worker 
writeNopData(uint64_t Count,MCObjectWriter * OW) const56*9880d681SAndroid Build Coastguard Worker bool BPFAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
57*9880d681SAndroid Build Coastguard Worker   if ((Count % 8) != 0)
58*9880d681SAndroid Build Coastguard Worker     return false;
59*9880d681SAndroid Build Coastguard Worker 
60*9880d681SAndroid Build Coastguard Worker   for (uint64_t i = 0; i < Count; i += 8)
61*9880d681SAndroid Build Coastguard Worker     OW->write64(0x15000000);
62*9880d681SAndroid Build Coastguard Worker 
63*9880d681SAndroid Build Coastguard Worker   return true;
64*9880d681SAndroid Build Coastguard Worker }
65*9880d681SAndroid Build Coastguard Worker 
applyFixup(const MCFixup & Fixup,char * Data,unsigned DataSize,uint64_t Value,bool IsPCRel) const66*9880d681SAndroid Build Coastguard Worker void BPFAsmBackend::applyFixup(const MCFixup &Fixup, char *Data,
67*9880d681SAndroid Build Coastguard Worker                                unsigned DataSize, uint64_t Value,
68*9880d681SAndroid Build Coastguard Worker                                bool IsPCRel) const {
69*9880d681SAndroid Build Coastguard Worker 
70*9880d681SAndroid Build Coastguard Worker   if (Fixup.getKind() == FK_SecRel_4 || Fixup.getKind() == FK_SecRel_8) {
71*9880d681SAndroid Build Coastguard Worker     assert(Value == 0);
72*9880d681SAndroid Build Coastguard Worker   } else if (Fixup.getKind() == FK_Data_4 || Fixup.getKind() == FK_Data_8) {
73*9880d681SAndroid Build Coastguard Worker     unsigned Size = Fixup.getKind() == FK_Data_4 ? 4 : 8;
74*9880d681SAndroid Build Coastguard Worker 
75*9880d681SAndroid Build Coastguard Worker     for (unsigned i = 0; i != Size; ++i) {
76*9880d681SAndroid Build Coastguard Worker       unsigned Idx = IsLittleEndian ? i : Size - i;
77*9880d681SAndroid Build Coastguard Worker       Data[Fixup.getOffset() + Idx] = uint8_t(Value >> (i * 8));
78*9880d681SAndroid Build Coastguard Worker     }
79*9880d681SAndroid Build Coastguard Worker   } else {
80*9880d681SAndroid Build Coastguard Worker     assert(Fixup.getKind() == FK_PCRel_2);
81*9880d681SAndroid Build Coastguard Worker     Value = (uint16_t)((Value - 8) / 8);
82*9880d681SAndroid Build Coastguard Worker     if (IsLittleEndian) {
83*9880d681SAndroid Build Coastguard Worker       Data[Fixup.getOffset() + 2] = Value & 0xFF;
84*9880d681SAndroid Build Coastguard Worker       Data[Fixup.getOffset() + 3] = Value >> 8;
85*9880d681SAndroid Build Coastguard Worker     } else {
86*9880d681SAndroid Build Coastguard Worker       Data[Fixup.getOffset() + 2] = Value >> 8;
87*9880d681SAndroid Build Coastguard Worker       Data[Fixup.getOffset() + 3] = Value & 0xFF;
88*9880d681SAndroid Build Coastguard Worker     }
89*9880d681SAndroid Build Coastguard Worker   }
90*9880d681SAndroid Build Coastguard Worker }
91*9880d681SAndroid Build Coastguard Worker 
createObjectWriter(raw_pwrite_stream & OS) const92*9880d681SAndroid Build Coastguard Worker MCObjectWriter *BPFAsmBackend::createObjectWriter(raw_pwrite_stream &OS) const {
93*9880d681SAndroid Build Coastguard Worker   return createBPFELFObjectWriter(OS, 0, IsLittleEndian);
94*9880d681SAndroid Build Coastguard Worker }
95*9880d681SAndroid Build Coastguard Worker }
96*9880d681SAndroid Build Coastguard Worker 
createBPFAsmBackend(const Target & T,const MCRegisterInfo & MRI,const Triple & TT,StringRef CPU)97*9880d681SAndroid Build Coastguard Worker MCAsmBackend *llvm::createBPFAsmBackend(const Target &T,
98*9880d681SAndroid Build Coastguard Worker                                         const MCRegisterInfo &MRI,
99*9880d681SAndroid Build Coastguard Worker                                         const Triple &TT, StringRef CPU) {
100*9880d681SAndroid Build Coastguard Worker   return new BPFAsmBackend(/*IsLittleEndian=*/true);
101*9880d681SAndroid Build Coastguard Worker }
102*9880d681SAndroid Build Coastguard Worker 
createBPFbeAsmBackend(const Target & T,const MCRegisterInfo & MRI,const Triple & TT,StringRef CPU)103*9880d681SAndroid Build Coastguard Worker MCAsmBackend *llvm::createBPFbeAsmBackend(const Target &T,
104*9880d681SAndroid Build Coastguard Worker                                           const MCRegisterInfo &MRI,
105*9880d681SAndroid Build Coastguard Worker                                           const Triple &TT, StringRef CPU) {
106*9880d681SAndroid Build Coastguard Worker   return new BPFAsmBackend(/*IsLittleEndian=*/false);
107*9880d681SAndroid Build Coastguard Worker }
108