aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjjasmine <tanghocle456@gmail.com>2024-06-10 16:54:34 -0700
committerArthur Cohen <arthur.cohen@embecosm.com>2025-03-17 16:35:47 +0100
commitc1662670f70e8c06164da58a2b020dcd89ae75d6 (patch)
tree382a372a7004cb74873a11519ee672109a2f035e
parent83465864dbddcebca788df417783eb4e074626f8 (diff)
downloadgcc-c1662670f70e8c06164da58a2b020dcd89ae75d6.zip
gcc-c1662670f70e8c06164da58a2b020dcd89ae75d6.tar.gz
gcc-c1662670f70e8c06164da58a2b020dcd89ae75d6.tar.bz2
gccrs: Partial support for operand
gcc/rust/ChangeLog: * ast/rust-expr.h (struct InlineAsmOperand): Partial support for operand * expand/rust-macro-builtins-asm.cc (parse_reg_operand): Likewise. (parse_label): Likewise. * expand/rust-macro-builtins-asm.h (parse_label): Likewise.
-rw-r--r--gcc/rust/ast/rust-expr.h38
-rw-r--r--gcc/rust/expand/rust-macro-builtins-asm.cc62
-rw-r--r--gcc/rust/expand/rust-macro-builtins-asm.h4
3 files changed, 97 insertions, 7 deletions
diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 30146b2..ba413da 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -7,6 +7,7 @@
#include "rust-macro.h"
#include "rust-operators.h"
#include "rust-system.h"
+#include <memory>
namespace Rust {
namespace AST {
@@ -4777,6 +4778,7 @@ struct InlineAsmOperand
SplitInOut,
Const,
Sym,
+ Label,
};
struct In
@@ -4933,6 +4935,34 @@ struct InlineAsmOperand
return *this;
}
};
+
+ struct Label
+ {
+ std::string label_name;
+ std::unique_ptr<Expr> expr;
+
+ Label () {}
+
+ Label (tl::optional<std::string> label_name, std::unique_ptr<Expr> expr)
+ : expr (std::move (expr))
+ {
+ if (label_name.has_value ())
+ this->label_name = label_name.value ();
+ }
+ Label (const struct Label &other)
+ {
+ if (other.expr)
+ expr = std::unique_ptr<Expr> (other.expr->clone_expr ());
+ }
+
+ Label operator= (const struct Label &other)
+ {
+ if (other.expr)
+ expr = std::unique_ptr<Expr> (other.expr->clone_expr ());
+ return *this;
+ }
+ };
+
RegisterType register_type;
struct In in;
@@ -4941,6 +4971,7 @@ struct InlineAsmOperand
struct SplitInOut split_in_out;
struct Const cnst;
struct Sym sym;
+ struct Label label;
InlineAsmOperand () {}
InlineAsmOperand (const InlineAsmOperand &other)
@@ -4992,6 +5023,13 @@ struct InlineAsmOperand
this->sym = reg.value ();
}
+ void set_label (const tl::optional<struct Label> &reg)
+ {
+ this->register_type = Label;
+ if (reg.has_value ())
+ this->label = reg.value ();
+ }
+
location_t locus;
};
diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc b/gcc/rust/expand/rust-macro-builtins-asm.cc
index d1f6897..47a4760 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.cc
+++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
@@ -373,19 +373,30 @@ parse_reg_operand (Parser<MacroInvocLexer> &parser, TokenId last_token_id,
}
else if (parser.peek_current_token ()->get_id () == CONST)
{
- // TODO: Please handle const
- rust_unreachable ();
- return tl::nullopt;
+ // TODO: Please handle const with parse_expr instead.
+ auto anon_const
+ = parse_format_string (parser, last_token_id, inline_asm_ctx);
+ reg_operand.set_cnst (tl::nullopt);
+ return reg_operand;
}
- else if (false && check_identifier (parser, "sym"))
+ else if (check_identifier (parser, "sym"))
{
- // TODO: Please handle sym
+ // TODO: Please handle sym, which needs ExprKind::Path in Rust's asm.rs
rust_unreachable ();
return tl::nullopt;
}
- else if (false && check_identifier (parser, "label"))
+ else if (auto label_str = parse_label (parser, last_token_id, inline_asm_ctx))
+ {
+ auto block = parser.parse_block_expr ();
+ struct AST::InlineAsmOperand::Label label (label_str,
+ block ? block->clone_expr ()
+ : nullptr);
+ reg_operand.set_label (label);
+ return reg_operand;
+ }
+ else if (inline_asm_ctx.allows_templates ())
{
- // TODO: Please handle label
+ // TODO: If we allow templating, do sth here
rust_unreachable ();
return tl::nullopt;
}
@@ -701,4 +712,41 @@ parse_asm (location_t invoc_locus, AST::MacroInvocData &invoc,
return fragment_ast;
}
+tl::optional<std::string>
+parse_label (Parser<MacroInvocLexer> &parser, TokenId last_token_id,
+ InlineAsmContext &inline_asm_ctx)
+{
+ auto token = parser.peek_current_token ();
+
+ if (token->get_id () != last_token_id && token->get_id () == STRING_LITERAL)
+ {
+ // very nice, we got a string.
+ auto label = token->as_string ();
+
+ bool flag = true;
+ if (label.empty () || label.back () != ':')
+ flag = false; // Check if string is empty or does not end with a colon
+
+ // Check if all characters before the last colon are digits
+ for (int i = 0; i < label.length () - 1 && flag == true; i++)
+ {
+ if (label[i] < '0' || label[i] > '9')
+ flag = false;
+ }
+
+ if (flag == true)
+ {
+ parser.skip_token ();
+ return token->as_string ();
+ }
+ else
+ {
+ return tl::nullopt;
+ }
+ }
+ else
+ {
+ return tl::nullopt;
+ }
+}
} // namespace Rust
diff --git a/gcc/rust/expand/rust-macro-builtins-asm.h b/gcc/rust/expand/rust-macro-builtins-asm.h
index 1ed3148..267c1b6 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.h
+++ b/gcc/rust/expand/rust-macro-builtins-asm.h
@@ -72,6 +72,10 @@ tl::optional<std::string>
parse_format_string (Parser<MacroInvocLexer> &parser, TokenId last_token_id,
InlineAsmContext &inline_asm_ctx);
+tl::optional<std::string>
+parse_label (Parser<MacroInvocLexer> &parser, TokenId last_token_id,
+ InlineAsmContext &inline_asm_ctx);
+
std::set<std::string> potentially_nonpromoted_keywords
= {"in", "out", "lateout", "inout", "inlateout", "const", "sym", "label"};