1 //===-- RISCVAsmBackend.cpp - RISCV 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/RISCVMCTargetDesc.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 RISCVAsmBackend : public MCAsmBackend {
27   uint8_t OSABI;
28   bool Is64Bit;
29 
30 public:
31   RISCVAsmBackend(uint8_t OSABI, bool Is64Bit)
32       : MCAsmBackend(), OSABI(OSABI), Is64Bit(Is64Bit) {}
33   ~RISCVAsmBackend() override {}
34 
35   void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
36                   uint64_t Value, bool IsPCRel) const override;
37 
38   MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override;
39 
40   bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
41                             const MCRelaxableFragment *DF,
42                             const MCAsmLayout &Layout) const override {
43     return false;
44   }
45 
46   unsigned getNumFixupKinds() const override { return 1; }
47 
48   bool mayNeedRelaxation(const MCInst &Inst) const override { return false; }
49 
50   void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
51                         MCInst &Res) const override {
52 
53     llvm_unreachable("RISCVAsmBackend::relaxInstruction() unimplemented");
54   }
55 
56   bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override;
57 };
58 
59 bool RISCVAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
60   // Once support for the compressed instruction set is added, we will be able
61   // to conditionally support 16-bit NOPs
62   if ((Count % 4) != 0)
63     return false;
64 
65   // The canonical nop on RISC-V is addi x0, x0, 0
66   for (uint64_t i = 0; i < Count; i += 4)
67     OW->write32(0x13);
68 
69   return true;
70 }
71 
72 void RISCVAsmBackend::applyFixup(const MCFixup &Fixup, char *Data,
73                                  unsigned DataSize, uint64_t Value,
74                                  bool IsPCRel) const {
75   return;
76 }
77 
78 MCObjectWriter *
79 RISCVAsmBackend::createObjectWriter(raw_pwrite_stream &OS) const {
80   return createRISCVELFObjectWriter(OS, OSABI, Is64Bit);
81 }
82 
83 } // end anonymous namespace
84 
85 MCAsmBackend *llvm::createRISCVAsmBackend(const Target &T,
86                                           const MCRegisterInfo &MRI,
87                                           const Triple &TT, StringRef CPU,
88                                           const MCTargetOptions &Options) {
89   uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS());
90   return new RISCVAsmBackend(OSABI, TT.isArch64Bit());
91 }
92