1 //===-- RISCVAsmBackend.h - 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 #ifndef LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVASMBACKEND_H 11 #define LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVASMBACKEND_H 12 13 #include "MCTargetDesc/RISCVFixupKinds.h" 14 #include "MCTargetDesc/RISCVMCTargetDesc.h" 15 #include "llvm/MC/MCAsmBackend.h" 16 #include "llvm/MC/MCFixupKindInfo.h" 17 #include "llvm/MC/MCSubtargetInfo.h" 18 19 namespace llvm { 20 class MCAssembler; 21 class MCObjectTargetWriter; 22 class raw_ostream; 23 24 class RISCVAsmBackend : public MCAsmBackend { 25 const MCSubtargetInfo &STI; 26 uint8_t OSABI; 27 bool Is64Bit; 28 bool ForceRelocs = false; 29 30 public: RISCVAsmBackend(const MCSubtargetInfo & STI,uint8_t OSABI,bool Is64Bit)31 RISCVAsmBackend(const MCSubtargetInfo &STI, uint8_t OSABI, bool Is64Bit) 32 : MCAsmBackend(support::little), STI(STI), OSABI(OSABI), 33 Is64Bit(Is64Bit) {} ~RISCVAsmBackend()34 ~RISCVAsmBackend() override {} 35 setForceRelocs()36 void setForceRelocs() { ForceRelocs = true; } 37 38 // Generate diff expression relocations if the relax feature is enabled or had 39 // previously been enabled, otherwise it is safe for the assembler to 40 // calculate these internally. requiresDiffExpressionRelocations()41 bool requiresDiffExpressionRelocations() const override { 42 return STI.getFeatureBits()[RISCV::FeatureRelax] || ForceRelocs; 43 } 44 void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, 45 const MCValue &Target, MutableArrayRef<char> Data, 46 uint64_t Value, bool IsResolved, 47 const MCSubtargetInfo *STI) const override; 48 49 std::unique_ptr<MCObjectTargetWriter> 50 createObjectTargetWriter() const override; 51 52 bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, 53 const MCValue &Target) override; 54 fixupNeedsRelaxation(const MCFixup & Fixup,uint64_t Value,const MCRelaxableFragment * DF,const MCAsmLayout & Layout)55 bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, 56 const MCRelaxableFragment *DF, 57 const MCAsmLayout &Layout) const override { 58 llvm_unreachable("Handled by fixupNeedsRelaxationAdvanced"); 59 } 60 61 bool fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, bool Resolved, 62 uint64_t Value, 63 const MCRelaxableFragment *DF, 64 const MCAsmLayout &Layout, 65 const bool WasForced) const override; 66 getNumFixupKinds()67 unsigned getNumFixupKinds() const override { 68 return RISCV::NumTargetFixupKinds; 69 } 70 getFixupKindInfo(MCFixupKind Kind)71 const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override { 72 const static MCFixupKindInfo Infos[] = { 73 // This table *must* be in the order that the fixup_* kinds are defined in 74 // RISCVFixupKinds.h. 75 // 76 // name offset bits flags 77 { "fixup_riscv_hi20", 12, 20, 0 }, 78 { "fixup_riscv_lo12_i", 20, 12, 0 }, 79 { "fixup_riscv_lo12_s", 0, 32, 0 }, 80 { "fixup_riscv_pcrel_hi20", 12, 20, MCFixupKindInfo::FKF_IsPCRel }, 81 { "fixup_riscv_pcrel_lo12_i", 20, 12, MCFixupKindInfo::FKF_IsPCRel }, 82 { "fixup_riscv_pcrel_lo12_s", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, 83 { "fixup_riscv_jal", 12, 20, MCFixupKindInfo::FKF_IsPCRel }, 84 { "fixup_riscv_branch", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, 85 { "fixup_riscv_rvc_jump", 2, 11, MCFixupKindInfo::FKF_IsPCRel }, 86 { "fixup_riscv_rvc_branch", 0, 16, MCFixupKindInfo::FKF_IsPCRel }, 87 { "fixup_riscv_call", 0, 64, MCFixupKindInfo::FKF_IsPCRel }, 88 { "fixup_riscv_relax", 0, 0, 0 } 89 }; 90 static_assert((array_lengthof(Infos)) == RISCV::NumTargetFixupKinds, 91 "Not all fixup kinds added to Infos array"); 92 93 if (Kind < FirstTargetFixupKind) 94 return MCAsmBackend::getFixupKindInfo(Kind); 95 96 assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && 97 "Invalid kind!"); 98 return Infos[Kind - FirstTargetFixupKind]; 99 } 100 101 bool mayNeedRelaxation(const MCInst &Inst, 102 const MCSubtargetInfo &STI) const override; 103 unsigned getRelaxedOpcode(unsigned Op) const; 104 105 void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI, 106 MCInst &Res) const override; 107 108 109 bool writeNopData(raw_ostream &OS, uint64_t Count) const override; 110 }; 111 } 112 113 #endif 114