blob: 54d58480e109d81c05d1c97eee3f6ee1f27abfd6 [file] [log] [blame]
Alex Bradbury9c03e4c2018-11-12 14:25:07 +00001//===-- RISCVAsmBackend.h - RISCV Assembler Backend -----------------------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Alex Bradbury9c03e4c2018-11-12 14:25:07 +00006//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVASMBACKEND_H
10#define LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVASMBACKEND_H
11
12#include "MCTargetDesc/RISCVFixupKinds.h"
13#include "MCTargetDesc/RISCVMCTargetDesc.h"
Alex Bradburyfea49572019-03-09 09:28:06 +000014#include "Utils/RISCVBaseInfo.h"
Alex Bradbury9c03e4c2018-11-12 14:25:07 +000015#include "llvm/MC/MCAsmBackend.h"
16#include "llvm/MC/MCFixupKindInfo.h"
17#include "llvm/MC/MCSubtargetInfo.h"
18
19namespace llvm {
20class MCAssembler;
21class MCObjectTargetWriter;
22class raw_ostream;
23
24class RISCVAsmBackend : public MCAsmBackend {
25 const MCSubtargetInfo &STI;
26 uint8_t OSABI;
27 bool Is64Bit;
28 bool ForceRelocs = false;
Alex Bradburyfea49572019-03-09 09:28:06 +000029 const MCTargetOptions &TargetOptions;
30 RISCVABI::ABI TargetABI = RISCVABI::ABI_Unknown;
Alex Bradbury9c03e4c2018-11-12 14:25:07 +000031
32public:
Alex Bradburyfea49572019-03-09 09:28:06 +000033 RISCVAsmBackend(const MCSubtargetInfo &STI, uint8_t OSABI, bool Is64Bit,
34 const MCTargetOptions &Options)
35 : MCAsmBackend(support::little), STI(STI), OSABI(OSABI), Is64Bit(Is64Bit),
36 TargetOptions(Options) {
37 TargetABI = RISCVABI::computeTargetABI(
38 STI.getTargetTriple(), STI.getFeatureBits(), Options.getABIName());
39 }
Alex Bradbury9c03e4c2018-11-12 14:25:07 +000040 ~RISCVAsmBackend() override {}
41
42 void setForceRelocs() { ForceRelocs = true; }
43
44 // Generate diff expression relocations if the relax feature is enabled or had
45 // previously been enabled, otherwise it is safe for the assembler to
46 // calculate these internally.
47 bool requiresDiffExpressionRelocations() const override {
48 return STI.getFeatureBits()[RISCV::FeatureRelax] || ForceRelocs;
49 }
Shiva Chen5af037f2019-01-30 11:16:59 +000050
51 // Return Size with extra Nop Bytes for alignment directive in code section.
52 bool shouldInsertExtraNopBytesForCodeAlign(const MCAlignFragment &AF,
53 unsigned &Size) override;
54
55 // Insert target specific fixup type for alignment directive in code section.
56 bool shouldInsertFixupForCodeAlign(MCAssembler &Asm,
57 const MCAsmLayout &Layout,
58 MCAlignFragment &AF) override;
59
Alex Bradbury9c03e4c2018-11-12 14:25:07 +000060 void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
61 const MCValue &Target, MutableArrayRef<char> Data,
62 uint64_t Value, bool IsResolved,
63 const MCSubtargetInfo *STI) const override;
64
65 std::unique_ptr<MCObjectTargetWriter>
66 createObjectTargetWriter() const override;
67
Alex Bradbury9c03e4c2018-11-12 14:25:07 +000068 bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
Alex Bradburyeb3a64a2018-12-20 14:52:15 +000069 const MCValue &Target) override;
Alex Bradbury9c03e4c2018-11-12 14:25:07 +000070
71 bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
72 const MCRelaxableFragment *DF,
73 const MCAsmLayout &Layout) const override {
74 llvm_unreachable("Handled by fixupNeedsRelaxationAdvanced");
75 }
76
77 bool fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, bool Resolved,
78 uint64_t Value,
79 const MCRelaxableFragment *DF,
80 const MCAsmLayout &Layout,
81 const bool WasForced) const override;
82
83 unsigned getNumFixupKinds() const override {
84 return RISCV::NumTargetFixupKinds;
85 }
86
87 const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override {
88 const static MCFixupKindInfo Infos[] = {
89 // This table *must* be in the order that the fixup_* kinds are defined in
90 // RISCVFixupKinds.h.
91 //
92 // name offset bits flags
93 { "fixup_riscv_hi20", 12, 20, 0 },
94 { "fixup_riscv_lo12_i", 20, 12, 0 },
95 { "fixup_riscv_lo12_s", 0, 32, 0 },
96 { "fixup_riscv_pcrel_hi20", 12, 20, MCFixupKindInfo::FKF_IsPCRel },
97 { "fixup_riscv_pcrel_lo12_i", 20, 12, MCFixupKindInfo::FKF_IsPCRel },
98 { "fixup_riscv_pcrel_lo12_s", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
Alex Bradbury8eb87e52019-02-15 09:43:46 +000099 { "fixup_riscv_got_hi20", 12, 20, MCFixupKindInfo::FKF_IsPCRel },
Alex Bradbury9c03e4c2018-11-12 14:25:07 +0000100 { "fixup_riscv_jal", 12, 20, MCFixupKindInfo::FKF_IsPCRel },
101 { "fixup_riscv_branch", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
102 { "fixup_riscv_rvc_jump", 2, 11, MCFixupKindInfo::FKF_IsPCRel },
103 { "fixup_riscv_rvc_branch", 0, 16, MCFixupKindInfo::FKF_IsPCRel },
104 { "fixup_riscv_call", 0, 64, MCFixupKindInfo::FKF_IsPCRel },
Shiva Chen5af037f2019-01-30 11:16:59 +0000105 { "fixup_riscv_relax", 0, 0, 0 },
106 { "fixup_riscv_align", 0, 0, 0 }
Alex Bradbury9c03e4c2018-11-12 14:25:07 +0000107 };
108 static_assert((array_lengthof(Infos)) == RISCV::NumTargetFixupKinds,
109 "Not all fixup kinds added to Infos array");
110
111 if (Kind < FirstTargetFixupKind)
112 return MCAsmBackend::getFixupKindInfo(Kind);
113
114 assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
115 "Invalid kind!");
116 return Infos[Kind - FirstTargetFixupKind];
117 }
118
119 bool mayNeedRelaxation(const MCInst &Inst,
120 const MCSubtargetInfo &STI) const override;
121 unsigned getRelaxedOpcode(unsigned Op) const;
122
123 void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
124 MCInst &Res) const override;
125
126
127 bool writeNopData(raw_ostream &OS, uint64_t Count) const override;
Alex Bradburyfea49572019-03-09 09:28:06 +0000128
129 const MCTargetOptions &getTargetOptions() const { return TargetOptions; }
130 RISCVABI::ABI getTargetABI() const { return TargetABI; }
Alex Bradbury9c03e4c2018-11-12 14:25:07 +0000131};
132}
133
134#endif