diff options
| author | Richard-Qin-X <richard.qin.001@gmail.com> | 2026-08-09 18:31:49 +0800 |
|---|---|---|
| committer | Richard-Qin-X <richard.qin.001@gmail.com> | 2026-08-09 18:31:49 +0800 |
| commit | 379ff50dcc7ccf977379aee68fa9d10f69065d23 (patch) | |
| tree | e0fac3952d46d0bbcaea32bcfc6087c95fff2992 /backend/include/rcc/MC/MCInst.h | |
| parent | 495c675771f43cfa12ab7a426a538be72fec1805 (diff) | |
| download | rcc-project-379ff50dcc7ccf977379aee68fa9d10f69065d23.tar.gz rcc-project-379ff50dcc7ccf977379aee68fa9d10f69065d23.tar.xz | |
[MC] Implement RV64GC assembly emission
Diffstat (limited to 'backend/include/rcc/MC/MCInst.h')
| -rw-r--r-- | backend/include/rcc/MC/MCInst.h | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/backend/include/rcc/MC/MCInst.h b/backend/include/rcc/MC/MCInst.h new file mode 100644 index 0000000..c6da93b --- /dev/null +++ b/backend/include/rcc/MC/MCInst.h @@ -0,0 +1,174 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef RCC_MC_MCINST_H +#define RCC_MC_MCINST_H + +#include "rcc/MC/MCExpr.h" + +#include <cstddef> +#include <cstdint> +#include <span> +#include <utility> +#include <variant> +#include <vector> + +namespace rcc::mc { + +class MCRegister final { +public: + constexpr MCRegister() noexcept = default; + + [[nodiscard]] static constexpr MCRegister fromValue(std::uint32_t Value) noexcept { + return MCRegister(Value); + } + + [[nodiscard]] constexpr std::uint32_t value() const noexcept { + return Value; + } + + [[nodiscard]] constexpr bool isValid() const noexcept { + return Value != 0; + } + + friend constexpr bool operator==(MCRegister Left, MCRegister Right) noexcept = default; + +private: + explicit constexpr MCRegister(std::uint32_t Value) noexcept : Value(Value) {} + + std::uint32_t Value = 0; +}; + +class MCOpcode final { +public: + constexpr MCOpcode() noexcept = default; + + [[nodiscard]] static constexpr MCOpcode fromValue(std::uint32_t Value) noexcept { + return MCOpcode(Value); + } + + [[nodiscard]] constexpr std::uint32_t value() const noexcept { + return Value; + } + + [[nodiscard]] constexpr bool isValid() const noexcept { + return Value != 0; + } + + friend constexpr bool operator==(MCOpcode Left, MCOpcode Right) noexcept = default; + +private: + explicit constexpr MCOpcode(std::uint32_t Value) noexcept : Value(Value) {} + + std::uint32_t Value = 0; +}; + +class MCOperand final { +public: + enum class Kind : std::uint8_t { + Register, + Immediate, + Float32Bits, + Float64Bits, + Expression, + }; + + [[nodiscard]] static MCOperand registerOperand(MCRegister Register) noexcept { + return MCOperand(Kind::Register, Register); + } + + [[nodiscard]] static MCOperand immediate(std::int64_t Value) noexcept { + return MCOperand(Kind::Immediate, Value); + } + + [[nodiscard]] static MCOperand float32Bits(std::uint32_t Value) noexcept { + return MCOperand(Kind::Float32Bits, Value); + } + + [[nodiscard]] static MCOperand float64Bits(std::uint64_t Value) noexcept { + return MCOperand(Kind::Float64Bits, Value); + } + + [[nodiscard]] static MCOperand expression(MCExprRef Value) { + return MCOperand(Kind::Expression, std::move(Value)); + } + + [[nodiscard]] Kind kind() const noexcept { + return OperandKind; + } + + [[nodiscard]] const MCRegister *registerValue() const noexcept { + return std::get_if<MCRegister>(&Storage); + } + + [[nodiscard]] const std::int64_t *immediateValue() const noexcept { + return std::get_if<std::int64_t>(&Storage); + } + + [[nodiscard]] const std::uint32_t *float32BitsValue() const noexcept { + return std::get_if<std::uint32_t>(&Storage); + } + + [[nodiscard]] const std::uint64_t *float64BitsValue() const noexcept { + return std::get_if<std::uint64_t>(&Storage); + } + + [[nodiscard]] const MCExprRef *expressionValue() const noexcept { + return std::get_if<MCExprRef>(&Storage); + } + +private: + using StorageT = std::variant<MCRegister, std::int64_t, std::uint32_t, std::uint64_t, MCExprRef>; + + MCOperand(Kind OperandKind, StorageT Storage) + : OperandKind(OperandKind), Storage(std::move(Storage)) {} + + Kind OperandKind; + StorageT Storage; +}; + +class MCInst final { +public: + explicit MCInst(MCOpcode InstructionOpcode) : InstructionOpcode(InstructionOpcode) {} + + [[nodiscard]] MCOpcode opcode() const noexcept { + return InstructionOpcode; + } + + void setFlags(std::uint32_t NewFlags) noexcept { + Flags = NewFlags; + } + + [[nodiscard]] std::uint32_t flags() const noexcept { + return Flags; + } + + void setSourceIdentity(std::uint64_t Identity) noexcept { + SourceIdentity = Identity; + } + + [[nodiscard]] std::uint64_t sourceIdentity() const noexcept { + return SourceIdentity; + } + + void reserveOperands(std::size_t Count) { + Operands.reserve(Count); + } + + void addOperand(MCOperand Operand) { + Operands.push_back(std::move(Operand)); + } + + [[nodiscard]] std::span<const MCOperand> operands() const noexcept { + return Operands; + } + +private: + MCOpcode InstructionOpcode; + std::uint32_t Flags = 0; + std::uint64_t SourceIdentity = 0; + std::vector<MCOperand> Operands; +}; + +} // namespace rcc::mc + +#endif // RCC_MC_MCINST_H |
