aboutsummaryrefslogtreecommitdiff
path: root/backend/lib/MC/MCInstPrinter.cpp
diff options
context:
space:
mode:
authorRichard-Qin-X <richard.qin.001@gmail.com>2026-08-09 18:31:49 +0800
committerRichard-Qin-X <richard.qin.001@gmail.com>2026-08-09 18:31:49 +0800
commit379ff50dcc7ccf977379aee68fa9d10f69065d23 (patch)
treee0fac3952d46d0bbcaea32bcfc6087c95fff2992 /backend/lib/MC/MCInstPrinter.cpp
parent495c675771f43cfa12ab7a426a538be72fec1805 (diff)
downloadrcc-project-379ff50dcc7ccf977379aee68fa9d10f69065d23.tar.gz
rcc-project-379ff50dcc7ccf977379aee68fa9d10f69065d23.tar.xz
[MC] Implement RV64GC assembly emission
Diffstat (limited to 'backend/lib/MC/MCInstPrinter.cpp')
-rw-r--r--backend/lib/MC/MCInstPrinter.cpp170
1 files changed, 170 insertions, 0 deletions
diff --git a/backend/lib/MC/MCInstPrinter.cpp b/backend/lib/MC/MCInstPrinter.cpp
new file mode 100644
index 0000000..1af6e4e
--- /dev/null
+++ b/backend/lib/MC/MCInstPrinter.cpp
@@ -0,0 +1,170 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "rcc/MC/MCInstPrinter.h"
+
+#include "rcc/MC/MCExpr.h"
+
+#include <cctype>
+#include <cstddef>
+#include <cstdint>
+#include <string>
+#include <string_view>
+
+namespace rcc::mc {
+namespace {
+
+[[nodiscard]] bool isBareSymbolName(std::string_view Name) noexcept {
+ if (Name.empty())
+ return false;
+ const auto Initial = [](unsigned char Character) {
+ return std::isalpha(Character) != 0 || Character == '_' || Character == '.' || Character == '$';
+ };
+ const auto Following = [](unsigned char Character) {
+ return std::isalnum(Character) != 0 || Character == '_' || Character == '.' || Character == '$';
+ };
+ if (!Initial(static_cast<unsigned char>(Name.front())))
+ return false;
+ for (const char Character : Name.substr(1)) {
+ if (!Following(static_cast<unsigned char>(Character)))
+ return false;
+ }
+ return true;
+}
+
+[[nodiscard]] std::string_view unarySpelling(MCUnaryOperator Operator) noexcept {
+ switch (Operator) {
+ case MCUnaryOperator::Plus:
+ return "+";
+ case MCUnaryOperator::Minus:
+ return "-";
+ case MCUnaryOperator::BitwiseNot:
+ return "~";
+ case MCUnaryOperator::LogicalNot:
+ return "!";
+ }
+ return {};
+}
+
+[[nodiscard]] std::string_view binarySpelling(MCBinaryOperator Operator) noexcept {
+ switch (Operator) {
+ case MCBinaryOperator::Add:
+ return "+";
+ case MCBinaryOperator::Subtract:
+ return "-";
+ case MCBinaryOperator::Multiply:
+ return "*";
+ case MCBinaryOperator::Divide:
+ return "/";
+ case MCBinaryOperator::Modulo:
+ return "%";
+ case MCBinaryOperator::ShiftLeft:
+ return "<<";
+ case MCBinaryOperator::ShiftRight:
+ return ">>";
+ case MCBinaryOperator::BitwiseAnd:
+ return "&";
+ case MCBinaryOperator::BitwiseOr:
+ return "|";
+ case MCBinaryOperator::BitwiseXor:
+ return "^";
+ case MCBinaryOperator::LogicalAnd:
+ return "&&";
+ case MCBinaryOperator::LogicalOr:
+ return "||";
+ case MCBinaryOperator::Equal:
+ return "==";
+ case MCBinaryOperator::NotEqual:
+ return "!=";
+ case MCBinaryOperator::Less:
+ return "<";
+ case MCBinaryOperator::LessEqual:
+ return "<=";
+ case MCBinaryOperator::Greater:
+ return ">";
+ case MCBinaryOperator::GreaterEqual:
+ return ">=";
+ }
+ return {};
+}
+
+[[nodiscard]] Expected<std::string>
+printExpressionImpl(const MCExpr &Expression, const MCInstPrinter &Printer, std::size_t Depth) {
+ if (Depth > 256)
+ return makeUnexpected(ErrorCode::AssemblyLoweringFailed,
+ "MC expression exceeds the assembly printing depth limit");
+
+ switch (Expression.kind()) {
+ case MCExpr::Kind::Constant:
+ return std::to_string(*Expression.getIf<std::int64_t>());
+ case MCExpr::Kind::SymbolRef: {
+ const auto *Reference = Expression.getIf<MCSymbolRefExpr>();
+ if (Reference == nullptr || !Reference->Symbol)
+ return makeUnexpected(ErrorCode::InternalError, "MC symbol expression storage is invalid");
+ return printMCSymbolName(Reference->Symbol->name());
+ }
+ case MCExpr::Kind::Unary: {
+ const auto *Unary = Expression.getIf<MCUnaryExpr>();
+ if (Unary == nullptr || !Unary->Operand)
+ return makeUnexpected(ErrorCode::InternalError, "MC unary expression storage is invalid");
+ auto Operand = printExpressionImpl(*Unary->Operand, Printer, Depth + 1);
+ if (!Operand)
+ return std::unexpected(Operand.error());
+ return std::string(unarySpelling(Unary->Operator)) + "(" + *Operand + ")";
+ }
+ case MCExpr::Kind::Binary: {
+ const auto *Binary = Expression.getIf<MCBinaryExpr>();
+ if (Binary == nullptr || !Binary->Left || !Binary->Right)
+ return makeUnexpected(ErrorCode::InternalError, "MC binary expression storage is invalid");
+ auto Left = printExpressionImpl(*Binary->Left, Printer, Depth + 1);
+ if (!Left)
+ return std::unexpected(Left.error());
+ auto Right = printExpressionImpl(*Binary->Right, Printer, Depth + 1);
+ if (!Right)
+ return std::unexpected(Right.error());
+ return "(" + *Left + std::string(binarySpelling(Binary->Operator)) + *Right + ")";
+ }
+ case MCExpr::Kind::Target: {
+ const auto *Target = Expression.getIf<MCTargetExpr>();
+ if (Target == nullptr || !Target->Operand)
+ return makeUnexpected(ErrorCode::InternalError, "target MC expression storage is invalid");
+ auto Operand = printExpressionImpl(*Target->Operand, Printer, Depth + 1);
+ if (!Operand)
+ return std::unexpected(Operand.error());
+ return Printer.printTargetExpression(Target->Kind, *Operand);
+ }
+ }
+ return makeUnexpected(ErrorCode::InternalError, "MC expression kind is invalid");
+}
+
+} // namespace
+
+Expected<std::string> printMCSymbolName(std::string_view Name) {
+ if (Name.empty())
+ return makeUnexpected(ErrorCode::AssemblyLoweringFailed, "MC symbol name cannot be empty");
+ if (isBareSymbolName(Name))
+ return std::string(Name);
+
+ std::string Result;
+ Result.push_back('"');
+ for (const char RawCharacter : Name) {
+ const auto Character = static_cast<unsigned char>(RawCharacter);
+ if (Character == 0 || Character == '\n' || Character == '\r' || Character == 0x7fU) {
+ return makeUnexpected(ErrorCode::AssemblyLoweringFailed,
+ "MC symbol name contains a non-printable character");
+ }
+ if (Character == '"' || Character == '\\')
+ Result.push_back('\\');
+ Result.push_back(static_cast<char>(Character));
+ }
+ Result.push_back('"');
+ return Result;
+}
+
+Expected<std::string> printMCExpression(const MCExpr &Expression, const MCInstPrinter &Printer) {
+ auto Verification = Expression.verify();
+ if (!Verification)
+ return std::unexpected(Verification.error());
+ return printExpressionImpl(Expression, Printer, 1);
+}
+
+} // namespace rcc::mc