https://gcc.gnu.org/g:68287a532c09dca6ef0c473db726ff385d0e7edb

commit r16-2964-g68287a532c09dca6ef0c473db726ff385d0e7edb
Author: Pierre-Emmanuel Patry <pierre-emmanuel.pa...@embecosm.com>
Date:   Tue Jul 29 13:48:17 2025 +0200

    gccrs: Add input/output from inout and split in out
    
    Inline assembly was incomplete and input/output from inout or split in
    out were not handled.
    
    gcc/rust/ChangeLog:
    
            * backend/rust-compile-asm.cc (get_out_expr): Return valid output 
from
            an operand.
            (CompileAsm::asm_construct_outputs): Handle every output
            (get_in_expr): Return valid input from an operand.
            (CompileAsm::asm_construct_inputs): Handle every input
    
    Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.pa...@embecosm.com>

Diff:
---
 gcc/rust/backend/rust-compile-asm.cc | 105 +++++++++++++++++++++++------------
 1 file changed, 71 insertions(+), 34 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-asm.cc 
b/gcc/rust/backend/rust-compile-asm.cc
index 7351cf0c5671..b7143a817af5 100644
--- a/gcc/rust/backend/rust-compile-asm.cc
+++ b/gcc/rust/backend/rust-compile-asm.cc
@@ -74,57 +74,94 @@ CompileAsm::asm_construct_string_tree (HIR::InlineAsm &expr)
   return Backend::string_constant_expression (result);
 }
 
+tl::optional<std::reference_wrapper<HIR::Expr>>
+get_out_expr (HIR::InlineAsmOperand &operand)
+{
+  switch (operand.get_register_type ())
+    {
+    case HIR::InlineAsmOperand::RegisterType::Out:
+      return *operand.get_out ().expr;
+    case HIR::InlineAsmOperand::RegisterType::InOut:
+      return *operand.get_in_out ().expr;
+    case HIR::InlineAsmOperand::RegisterType::SplitInOut:
+      return *operand.get_split_in_out ().out_expr;
+    case HIR::InlineAsmOperand::RegisterType::Const:
+    case HIR::InlineAsmOperand::RegisterType::Sym:
+    case HIR::InlineAsmOperand::RegisterType::Label:
+    case HIR::InlineAsmOperand::RegisterType::In:
+      break;
+    }
+  return tl::nullopt;
+}
+
 tree
 CompileAsm::asm_construct_outputs (HIR::InlineAsm &expr)
 {
   // TODO: Do i need to do this?
 
   tree head = NULL_TREE;
-  for (auto &output : expr.get_operands ())
+  for (auto &operand : expr.get_operands ())
     {
-      if (output.get_register_type ()
-         == AST::InlineAsmOperand::RegisterType::Out)
-       {
-         auto out = output.get_out ();
-
-         tree out_tree = CompileExpr::Compile (*out.expr, this->ctx);
-         // expects a tree list
-         // TODO: This assumes that the output is a register
-         std::string expr_name = "=r";
-         auto name = build_string (expr_name.size () + 1, expr_name.c_str ());
-         head
-           = chainon (head, build_tree_list (build_tree_list (NULL_TREE, name),
-                                             out_tree));
-
-         /*Backend::debug (head);*/
-         /*head = chainon (head, out_tree);*/
-       }
+      tl::optional<std::reference_wrapper<HIR::Expr>> out_expr
+       = get_out_expr (operand);
+      if (!out_expr.has_value ())
+       continue;
+
+      tree out_tree = CompileExpr::Compile (*out_expr, this->ctx);
+      // expects a tree list
+      // TODO: This assumes that the output is a register
+      std::string expr_name = "=r";
+      auto name = build_string (expr_name.size () + 1, expr_name.c_str ());
+      head = chainon (head, build_tree_list (build_tree_list (NULL_TREE, name),
+                                            out_tree));
+
+      /*Backend::debug (head);*/
+      /*head = chainon (head, out_tree);*/
     }
   return head;
 }
 
+tl::optional<std::reference_wrapper<HIR::Expr>>
+get_in_expr (HIR::InlineAsmOperand &operand)
+{
+  switch (operand.get_register_type ())
+    {
+    case HIR::InlineAsmOperand::RegisterType::In:
+      return *operand.get_in ().expr;
+    case HIR::InlineAsmOperand::RegisterType::InOut:
+      return *operand.get_in_out ().expr;
+    case HIR::InlineAsmOperand::RegisterType::SplitInOut:
+      return *operand.get_split_in_out ().in_expr;
+    case HIR::InlineAsmOperand::RegisterType::Const:
+    case HIR::InlineAsmOperand::RegisterType::Sym:
+    case HIR::InlineAsmOperand::RegisterType::Label:
+    case HIR::InlineAsmOperand::RegisterType::Out:
+      break;
+    }
+  return tl::nullopt;
+}
+
 tree
 CompileAsm::asm_construct_inputs (HIR::InlineAsm &expr)
 {
   // TODO: Do i need to do this?
   tree head = NULL_TREE;
-  for (auto &input : expr.get_operands ())
+  for (auto &operand : expr.get_operands ())
     {
-      if (input.get_register_type () == 
AST::InlineAsmOperand::RegisterType::In)
-       {
-         auto in = input.get_in ();
-
-         tree in_tree = CompileExpr::Compile (*in.expr, this->ctx);
-         // expects a tree list
-         // TODO: This assumes that the input is a register
-         std::string expr_name = "r";
-         auto name = build_string (expr_name.size () + 1, expr_name.c_str ());
-         head
-           = chainon (head, build_tree_list (build_tree_list (NULL_TREE, name),
-                                             in_tree));
-
-         /*head = chainon (head, out_tree);*/
-       }
+      tl::optional<std::reference_wrapper<HIR::Expr>> in_expr
+       = get_in_expr (operand);
+      if (!in_expr.has_value ())
+       continue;
+
+      tree in_tree = CompileExpr::Compile (*in_expr, this->ctx);
+      // expects a tree list
+      // TODO: This assumes that the input is a register
+      std::string expr_name = "r";
+      auto name = build_string (expr_name.size () + 1, expr_name.c_str ());
+      head = chainon (head, build_tree_list (build_tree_list (NULL_TREE, name),
+                                            in_tree));
+
+      /*head = chainon (head, out_tree);*/
     }
   return head;
 }

Reply via email to