Coverage Report

Created: 2026-02-14 07:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/keystone/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
Line
Count
Source
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
//===----------------------------------------------------------------------===//
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"
14
#include "Utils/RISCVBaseInfo.h"
15
#include "llvm/MC/MCAsmBackend.h"
16
#include "llvm/MC/MCFixupKindInfo.h"
17
#include "llvm/MC/MCSubtargetInfo.h"
18
#include "llvm/ADT/STLExtras.h"
19
20
21
namespace llvm_ks {
22
class MCAssembler;
23
class MCObjectWriter;
24
class raw_ostream;
25
26
class RISCVAsmBackend : public MCAsmBackend {
27
  
28
29
  Triple::OSType OSType;
30
  bool IsLittle; // Big or little endian
31
  bool Is64Bit;  // 32 or 64 bit words
32
  bool ForceRelocs = false;
33
  RISCVABI::ABI TargetABI = RISCVABI::ABI_Unknown;
34
  const MCSubtargetInfo &STI;
35
  const MCTargetOptions &TargetOptions;
36
  uint8_t OSABI;
37
38
public:
39
  RISCVAsmBackend(const Target &T, Triple::OSType OSType, bool IsLittle,
40
                 bool Is64Bit, const MCSubtargetInfo &STI, const MCTargetOptions &Options)
41
25.8k
      : MCAsmBackend(), OSType(OSType), IsLittle(IsLittle), Is64Bit(Is64Bit),STI(STI), TargetOptions(Options){
42
25.8k
    TargetABI = RISCVABI::computeTargetABI(
43
25.8k
        STI.getTargetTriple(), STI.getFeatureBits(), Options.getABIName());
44
25.8k
    RISCVFeatures::validate(STI.getTargetTriple(), STI.getFeatureBits());
45
    
46
25.8k
  }
47
0
  ~RISCVAsmBackend() override {}
48
49
20.7k
  void setForceRelocs() { ForceRelocs = true; }
50
51
  // Returns true if relocations will be forced for shouldForceRelocation by
52
  // default. This will be true if relaxation is enabled or had previously
53
  // been enabled.
54
0
  bool willForceRelocations() const {
55
0
    return ForceRelocs || STI.getFeatureBits()[RISCV::FeatureRelax];
56
0
  }
57
58
  // Generate diff expression relocations if the relax feature is enabled or had
59
  // previously been enabled, otherwise it is safe for the assembler to
60
  // calculate these internally.
61
0
  bool requiresDiffExpressionRelocations() const {
62
0
    return willForceRelocations();
63
0
  }
64
65
  // Return Size with extra Nop Bytes for alignment directive in code section.
66
  bool shouldInsertExtraNopBytesForCodeAlign(const MCAlignFragment &AF,
67
                                             unsigned &Size);
68
69
  // Insert target specific fixup type for alignment directive in code section.
70
  bool shouldInsertFixupForCodeAlign(MCAssembler &Asm,
71
                                     const MCAsmLayout &Layout,
72
                                     MCAlignFragment &AF);
73
74
  void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
75
                          uint64_t Value, bool IsPCRel, unsigned int &KsError) const override;
76
77
  MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override;
78
79
  bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
80
                             const MCValue &Target);
81
82
  bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
83
                            const MCRelaxableFragment *DF,
84
0
                            const MCAsmLayout &Layout, unsigned &KsError) const override {
85
0
    llvm_unreachable("Handled by fixupNeedsRelaxationAdvanced");
86
0
  }
87
88
  bool fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, bool Resolved,
89
                                    uint64_t Value,
90
                                    const MCRelaxableFragment *DF,
91
                                    const MCAsmLayout &Layout) const override;
92
93
1.17k
  unsigned getNumFixupKinds() const override {
94
1.17k
    return RISCV::NumTargetFixupKinds;
95
1.17k
  }
96
97
51.6k
  const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override {
98
51.6k
    const static MCFixupKindInfo Infos[] = {
99
      // This table *must* be in the order that the fixup_* kinds are defined in
100
      // RISCVFixupKinds.h.
101
      //
102
      // name                      offset bits  flags
103
51.6k
      { "fixup_riscv_hi20",         12,     20,  0 },
104
51.6k
      { "fixup_riscv_lo12_i",       20,     12,  0 },
105
51.6k
      { "fixup_riscv_lo12_s",        0,     32,  0 },
106
51.6k
      { "fixup_riscv_pcrel_hi20",   12,     20,  MCFixupKindInfo::FKF_IsPCRel },
107
51.6k
      { "fixup_riscv_pcrel_lo12_i", 20,     12,  MCFixupKindInfo::FKF_IsPCRel },
108
51.6k
      { "fixup_riscv_pcrel_lo12_s",  0,     32,  MCFixupKindInfo::FKF_IsPCRel },
109
51.6k
      { "fixup_riscv_got_hi20",     12,     20,  MCFixupKindInfo::FKF_IsPCRel },
110
51.6k
      { "fixup_riscv_tprel_hi20",   12,     20,  0 },
111
51.6k
      { "fixup_riscv_tprel_lo12_i", 20,     12,  0 },
112
51.6k
      { "fixup_riscv_tprel_lo12_s",  0,     32,  0 },
113
51.6k
      { "fixup_riscv_tprel_add",     0,      0,  0 },
114
51.6k
      { "fixup_riscv_tls_got_hi20", 12,     20,  MCFixupKindInfo::FKF_IsPCRel },
115
51.6k
      { "fixup_riscv_tls_gd_hi20",  12,     20,  MCFixupKindInfo::FKF_IsPCRel },
116
51.6k
      { "fixup_riscv_jal",          12,     20,  MCFixupKindInfo::FKF_IsPCRel },
117
51.6k
      { "fixup_riscv_branch",        0,     32,  MCFixupKindInfo::FKF_IsPCRel },
118
51.6k
      { "fixup_riscv_rvc_jump",      2,     11,  MCFixupKindInfo::FKF_IsPCRel },
119
51.6k
      { "fixup_riscv_rvc_branch",    0,     16,  MCFixupKindInfo::FKF_IsPCRel },
120
51.6k
      { "fixup_riscv_call",          0,     64,  MCFixupKindInfo::FKF_IsPCRel },
121
51.6k
      { "fixup_riscv_call_plt",      0,     64,  MCFixupKindInfo::FKF_IsPCRel },
122
51.6k
      { "fixup_riscv_relax",         0,      0,  0 },
123
51.6k
      { "fixup_riscv_align",         0,      0,  0 }
124
51.6k
    };
125
51.6k
    static_assert((array_lengthof(Infos)) == RISCV::NumTargetFixupKinds,
126
51.6k
                  "Not all fixup kinds added to Infos array");
127
128
51.6k
    if (Kind < FirstTargetFixupKind)
129
50.4k
      return MCAsmBackend::getFixupKindInfo(Kind);
130
131
51.6k
    assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
132
1.17k
           "Invalid kind!");
133
1.17k
    return Infos[Kind - FirstTargetFixupKind];
134
1.17k
  }
135
136
  bool mayNeedRelaxation(const MCInst &Inst) const override;
137
  unsigned getRelaxedOpcode(unsigned Op) const;
138
139
  void relaxInstruction(const MCInst &Inst,
140
                        MCInst &Res) const override;
141
142
143
  bool writeNopData(uint64_t Count, MCObjectWriter * OW) const override;
144
145
0
  const MCTargetOptions &getTargetOptions() const { return TargetOptions; }
146
25.8k
  RISCVABI::ABI getTargetABI() const { return TargetABI; }
147
};
148
}
149
150
#endif