[InstCombine] Signed saturation patterns
[llvm-core.git] / lib / Target / RISCV / MCTargetDesc / RISCVAsmBackend.h
blob254249c87dc88ea8773469418942233d076f983c
1 //===-- RISCVAsmBackend.h - RISCV Assembler Backend -----------------------===//
2 //
3 // 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
6 //
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVASMBACKEND_H
10 #define LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVASMBACKEND_H
12 #include "MCTargetDesc/RISCVFixupKinds.h"
13 #include "MCTargetDesc/RISCVMCTargetDesc.h"
14 #include "Utils/RISCVBaseInfo.h"
15 #include "llvm/MC/MCAsmBackend.h"
16 #include "llvm/MC/MCFixupKindInfo.h"
17 #include "llvm/MC/MCSubtargetInfo.h"
19 namespace llvm {
20 class MCAssembler;
21 class MCObjectTargetWriter;
22 class raw_ostream;
24 class RISCVAsmBackend : public MCAsmBackend {
25 const MCSubtargetInfo &STI;
26 uint8_t OSABI;
27 bool Is64Bit;
28 bool ForceRelocs = false;
29 const MCTargetOptions &TargetOptions;
30 RISCVABI::ABI TargetABI = RISCVABI::ABI_Unknown;
32 public:
33 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 RISCVFeatures::validate(STI.getTargetTriple(), STI.getFeatureBits());
41 ~RISCVAsmBackend() override {}
43 void setForceRelocs() { ForceRelocs = true; }
45 // Returns true if relocations will be forced for shouldForceRelocation by
46 // default. This will be true if relaxation is enabled or had previously
47 // been enabled.
48 bool willForceRelocations() const {
49 return ForceRelocs || STI.getFeatureBits()[RISCV::FeatureRelax];
52 // Generate diff expression relocations if the relax feature is enabled or had
53 // previously been enabled, otherwise it is safe for the assembler to
54 // calculate these internally.
55 bool requiresDiffExpressionRelocations() const override {
56 return willForceRelocations();
59 // Return Size with extra Nop Bytes for alignment directive in code section.
60 bool shouldInsertExtraNopBytesForCodeAlign(const MCAlignFragment &AF,
61 unsigned &Size) override;
63 // Insert target specific fixup type for alignment directive in code section.
64 bool shouldInsertFixupForCodeAlign(MCAssembler &Asm,
65 const MCAsmLayout &Layout,
66 MCAlignFragment &AF) override;
68 void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
69 const MCValue &Target, MutableArrayRef<char> Data,
70 uint64_t Value, bool IsResolved,
71 const MCSubtargetInfo *STI) const override;
73 std::unique_ptr<MCObjectTargetWriter>
74 createObjectTargetWriter() const override;
76 bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
77 const MCValue &Target) override;
79 bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
80 const MCRelaxableFragment *DF,
81 const MCAsmLayout &Layout) const override {
82 llvm_unreachable("Handled by fixupNeedsRelaxationAdvanced");
85 bool fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, bool Resolved,
86 uint64_t Value,
87 const MCRelaxableFragment *DF,
88 const MCAsmLayout &Layout,
89 const bool WasForced) const override;
91 unsigned getNumFixupKinds() const override {
92 return RISCV::NumTargetFixupKinds;
95 const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override {
96 const static MCFixupKindInfo Infos[] = {
97 // This table *must* be in the order that the fixup_* kinds are defined in
98 // RISCVFixupKinds.h.
100 // name offset bits flags
101 { "fixup_riscv_hi20", 12, 20, 0 },
102 { "fixup_riscv_lo12_i", 20, 12, 0 },
103 { "fixup_riscv_lo12_s", 0, 32, 0 },
104 { "fixup_riscv_pcrel_hi20", 12, 20, MCFixupKindInfo::FKF_IsPCRel },
105 { "fixup_riscv_pcrel_lo12_i", 20, 12, MCFixupKindInfo::FKF_IsPCRel },
106 { "fixup_riscv_pcrel_lo12_s", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
107 { "fixup_riscv_got_hi20", 12, 20, MCFixupKindInfo::FKF_IsPCRel },
108 { "fixup_riscv_tprel_hi20", 12, 20, 0 },
109 { "fixup_riscv_tprel_lo12_i", 20, 12, 0 },
110 { "fixup_riscv_tprel_lo12_s", 0, 32, 0 },
111 { "fixup_riscv_tprel_add", 0, 0, 0 },
112 { "fixup_riscv_tls_got_hi20", 12, 20, MCFixupKindInfo::FKF_IsPCRel },
113 { "fixup_riscv_tls_gd_hi20", 12, 20, MCFixupKindInfo::FKF_IsPCRel },
114 { "fixup_riscv_jal", 12, 20, MCFixupKindInfo::FKF_IsPCRel },
115 { "fixup_riscv_branch", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
116 { "fixup_riscv_rvc_jump", 2, 11, MCFixupKindInfo::FKF_IsPCRel },
117 { "fixup_riscv_rvc_branch", 0, 16, MCFixupKindInfo::FKF_IsPCRel },
118 { "fixup_riscv_call", 0, 64, MCFixupKindInfo::FKF_IsPCRel },
119 { "fixup_riscv_call_plt", 0, 64, MCFixupKindInfo::FKF_IsPCRel },
120 { "fixup_riscv_relax", 0, 0, 0 },
121 { "fixup_riscv_align", 0, 0, 0 }
123 static_assert((array_lengthof(Infos)) == RISCV::NumTargetFixupKinds,
124 "Not all fixup kinds added to Infos array");
126 if (Kind < FirstTargetFixupKind)
127 return MCAsmBackend::getFixupKindInfo(Kind);
129 assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
130 "Invalid kind!");
131 return Infos[Kind - FirstTargetFixupKind];
134 bool mayNeedRelaxation(const MCInst &Inst,
135 const MCSubtargetInfo &STI) const override;
136 unsigned getRelaxedOpcode(unsigned Op) const;
138 void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
139 MCInst &Res) const override;
142 bool writeNopData(raw_ostream &OS, uint64_t Count) const override;
144 const MCTargetOptions &getTargetOptions() const { return TargetOptions; }
145 RISCVABI::ABI getTargetABI() const { return TargetABI; }
149 #endif