aboutsummaryrefslogtreecommitdiff
path: root/backend/include/rcc/Target/RISCV/RISCVSubtarget.h
blob: 52e4b0370d884ddc3a36ca612d3ed9f45a4c0ab5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// SPDX-License-Identifier: GPL-3.0-or-later

#ifndef RCC_TARGET_RISCV_RISCVSUBTARGET_H
#define RCC_TARGET_RISCV_RISCVSUBTARGET_H

#include "rcc/CodeGen/CommandFlags.h"
#include "rcc/Support/Error.h"

#include <cstdint>
#include <memory>
#include <span>
#include <string>
#include <string_view>

namespace rcc {

class InstructionSelector;
class LegalizerInfo;
class TargetCallLowering;
class TargetFrameLowering;
class TargetSchedulingHooks;
class TargetSchedulingModel;

namespace riscv {

class RISCVRegisterBankInfo;

enum class RISCVExtension : std::uint8_t {
  I,
  M,
  A,
  F,
  D,
  C,
  Zba,
  Zbb,
  Zicsr,
  Zifencei,
  Zacas,
  Zabha,
  Zcmp,
  Count,
};

enum class RISCVSubtargetOption : std::uint8_t {
  DisablePostMISchedLoadClustering,
  DisablePostMISchedStoreClustering,
  FusionAddLoad,
  FusionAddMemory,
  FusionAddImmediateLoad,
  FusionAUIPCAddImmediate,
  FusionAUIPCLoad,
  FusionBitfieldExtract,
  FusionLoadDoubleAdd,
  FusionLogicImmediateRegister,
  FusionLogicRegisterImmediate,
  FusionLogicRegisterRegister,
  FusionLUIAddImmediate,
  FusionLUILoad,
  FusionMultiplyAdd,
  FusionShiftBitExtract,
  FusionShiftedAddLoad,
  FusionShiftedZeroExtendWord,
  FusionZeroExtendHalf,
  FusionZeroExtendWord,
  PreferWordInstructions,
  ReserveX6,
  ReserveX7,
  SaveRestore,
  TaggedGlobals,
  UnalignedScalarMemory,
  UsePostRAScheduler,
  Count,
};

enum class RISCVABI : std::uint8_t {
  LP64,
  LP64D,
};

[[nodiscard]] Expected<RISCVABI> parseRISCVABI(std::string_view Name);

class RISCVSubtargetFeatures final {
public:
  [[nodiscard]] static Expected<RISCVSubtargetFeatures>
  fromFeatureList(std::span<const std::string> Features);
  [[nodiscard]] static RISCVSubtargetFeatures rv64gc() noexcept;

  [[nodiscard]] bool has(RISCVExtension Extension) const noexcept;
  [[nodiscard]] bool has(RISCVSubtargetOption Option) const noexcept;
  [[nodiscard]] bool hasFeature(std::string_view Feature) const noexcept;

  friend bool operator==(const RISCVSubtargetFeatures &Left,
                         const RISCVSubtargetFeatures &Right) = default;

private:
  explicit constexpr RISCVSubtargetFeatures(std::uint16_t Enabled,
                                            std::uint32_t Options = 0) noexcept
      : Enabled(Enabled), Options(Options) {}

  std::uint16_t Enabled = 0;
  std::uint32_t Options = 0;
};

class RISCVSubtarget final {
public:
  explicit RISCVSubtarget(RISCVSubtargetFeatures Features,
                          RelocationModel Relocation = RelocationModel::Static,
                          CodeModel Code = CodeModel::Small, RISCVABI ABI = RISCVABI::LP64D);
  RISCVSubtarget(const RISCVSubtarget &) = delete;
  RISCVSubtarget &operator=(const RISCVSubtarget &) = delete;
  RISCVSubtarget(RISCVSubtarget &&) = delete;
  RISCVSubtarget &operator=(RISCVSubtarget &&) = delete;
  ~RISCVSubtarget();

  [[nodiscard]] const RISCVSubtargetFeatures &features() const noexcept {
    return Features;
  }

  [[nodiscard]] RelocationModel relocationModel() const noexcept {
    return Relocation;
  }

  [[nodiscard]] CodeModel codeModel() const noexcept {
    return Code;
  }

  [[nodiscard]] RISCVABI targetABI() const noexcept {
    return ABI;
  }

  [[nodiscard]] const TargetCallLowering *getCallLowering() const;
  [[nodiscard]] InstructionSelector *getInstructionSelector() const;
  [[nodiscard]] const LegalizerInfo *getLegalizerInfo() const;
  [[nodiscard]] const RISCVRegisterBankInfo *getRegBankInfo() const;
  [[nodiscard]] const TargetFrameLowering &frameLowering() const noexcept;
  [[nodiscard]] const TargetSchedulingModel &schedulingModel() const noexcept;

private:
  RISCVSubtargetFeatures Features;
  RelocationModel Relocation;
  CodeModel Code;
  RISCVABI ABI;
  std::unique_ptr<TargetFrameLowering> FrameLoweringInfo;
  mutable std::unique_ptr<TargetCallLowering> CallLoweringInfo;
  mutable std::unique_ptr<InstructionSelector> InstSelector;
  mutable std::unique_ptr<LegalizerInfo> Legalizer;
  mutable std::unique_ptr<RISCVRegisterBankInfo> RegBankInfo;
  std::unique_ptr<TargetSchedulingHooks> SchedulingHooks;
  std::unique_ptr<TargetSchedulingModel> SchedulingModel;
};

} // namespace riscv
} // namespace rcc

#endif // RCC_TARGET_RISCV_RISCVSUBTARGET_H