From: badumbatish <tanghocle...@gmail.com>

gcc/rust/ChangeLog:

        * backend/rust-compile-asm.cc (CompileAsm::add_stmt):
        Scaffolding code.
        (CompileAsm::asm_build_asm_stmt): Likewise.
        (CompileAsm::asm_build_expr): Likewise.
        (CompileAsm::asm_construct_string_tree): Likewise.
        * backend/rust-compile-asm.h: Likewise.
        * backend/rust-compile-expr.cc (CompileExpr::visit): Likewise.
---
 gcc/rust/backend/rust-compile-asm.cc  | 92 ++++++++++++++++++++++++++-
 gcc/rust/backend/rust-compile-asm.h   |  5 ++
 gcc/rust/backend/rust-compile-expr.cc |  1 +
 3 files changed, 97 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/backend/rust-compile-asm.cc 
b/gcc/rust/backend/rust-compile-asm.cc
index 5bc7bce07e6..bc11696ed10 100644
--- a/gcc/rust/backend/rust-compile-asm.cc
+++ b/gcc/rust/backend/rust-compile-asm.cc
@@ -5,10 +5,60 @@
 namespace Rust {
 namespace Compile {
 
+tree
+CompileAsm::add_stmt (tree t)
+{
+  enum tree_code code = TREE_CODE (t);
+
+  if (EXPR_P (t) && code != LABEL_EXPR)
+    {
+      if (!EXPR_HAS_LOCATION (t))
+       SET_EXPR_LOCATION (t, input_location);
+
+      /* When we expand a statement-tree, we must know whether or not the
+        statements are full-expressions.  We record that fact here.  */
+      if (STATEMENT_CODE_P (TREE_CODE (t)))
+       STMT_IS_FULL_EXPR_P (t) = stmts_are_full_exprs_p ();
+    }
+
+  if (code == LABEL_EXPR || code == CASE_LABEL_EXPR)
+    STATEMENT_LIST_HAS_LABEL (cur_stmt_list) = 1;
+
+  /* Add T to the statement-tree.  Non-side-effect statements need to be
+     recorded during statement expressions.  */
+  gcc_checking_assert (!stmt_list_stack->is_empty ());
+  append_to_statement_list_force (t, &cur_stmt_list);
+
+  return t;
+}
+tree
+CompileAsm::asm_build_asm_stmt (HIR::InlineAsm &expr)
+{
+  // From the implementation of c-typeck.cc
+  // tree
+  // build_asm_stmt (bool is_volatile, tree args)
+  //{
+  //   if (is_volatile)
+  //     ASM_VOLATILE_P (args) = 1;
+  //   return add_stmt (args);
+  // }
+  //
+  return add_stmt (asm_build_expr (expr));
+}
 tree
 CompileAsm::asm_build_expr (HIR::InlineAsm &expr)
 {
-  return NULL_TREE;
+  auto asm_expr = asm_build_stmt (asm_get_locus (expr), ASM_EXPR,
+                                 {asm_construct_string_tree (expr),
+                                  asm_construct_outputs (expr),
+                                  asm_construct_inputs (expr),
+                                  asm_construct_clobber_tree (expr),
+                                  asm_construct_label_tree (expr)});
+
+  ASM_BASIC_P (asm_expr) = CompileAsm::asm_is_simple (expr);
+  ASM_VOLATILE_P (asm_expr) = (false);
+  ASM_INLINE_P (asm_expr) = CompileAsm::asm_is_inline (expr);
+  return asm_expr;
   // return build_asm_expr (CompileAsm::asm_get_locus (expr),
   //                    CompileAsm::asm_construct_string_tree (expr),
   //                    CompileAsm::asm_construct_outputs (expr),
@@ -19,6 +69,43 @@ CompileAsm::asm_build_expr (HIR::InlineAsm &expr)
   //                    CompileAsm::asm_is_inline (expr));
 }
 
+tree
+CompileAsm::asm_build_stmt (
+  location_t loc, enum tree_code code,
+  const std::array<tree, CompileAsm::ASM_TREE_ARRAY_LENGTH> &trees)
+{
+  tree ret;
+  //  va_list p;
+  bool side_effects;
+
+  /* This function cannot be used to construct variably-sized nodes.  */
+  gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp);
+
+  // va_start (p, code);
+
+  ret = make_node (code);
+  TREE_TYPE (ret) = void_type_node;
+  SET_EXPR_LOCATION (ret, loc);
+
+  /* TREE_SIDE_EFFECTS will already be set for statements with
+     implicit side effects.  Here we make sure it is set for other
+     expressions by checking whether the parameters have side
+     effects.  */
+
+  side_effects = false;
+  for (size_t i = 0; i < trees.size (); i++)
+    {
+      tree t = trees[i];
+      if (t && !TYPE_P (t))
+       side_effects |= TREE_SIDE_EFFECTS (t);
+      TREE_OPERAND (ret, i) = t;
+    }
+
+  TREE_SIDE_EFFECTS (ret) |= side_effects;
+
+  // va_end (p);
+  return ret;
+}
 location_t
 CompileAsm::asm_get_locus (HIR::InlineAsm &expr)
 {
@@ -40,6 +127,9 @@ CompileAsm::asm_construct_string_tree (HIR::InlineAsm &expr)
       string_chain = tree_cons (NULL_TREE, string_tree, string_chain);
     }
   // Reverse the chain before returning
+
+  string_chain = nreverse (string_chain);
+
   return nreverse (string_chain);
 }
 tree
diff --git a/gcc/rust/backend/rust-compile-asm.h 
b/gcc/rust/backend/rust-compile-asm.h
index 58f0f51e9cf..fd25090cf98 100644
--- a/gcc/rust/backend/rust-compile-asm.h
+++ b/gcc/rust/backend/rust-compile-asm.h
@@ -29,7 +29,12 @@ namespace Compile {
 class CompileAsm
 {
 public:
+  static const int ASM_TREE_ARRAY_LENGTH = 5;
+  static tree add_stmt (tree);
+  static tree asm_build_asm_stmt (HIR::InlineAsm &);
   static tree asm_build_expr (HIR::InlineAsm &);
+  static tree asm_build_stmt (location_t, enum tree_code,
+                             const std::array<tree, ASM_TREE_ARRAY_LENGTH> &);
   static location_t asm_get_locus (HIR::InlineAsm &);
   static tree asm_construct_string_tree (HIR::InlineAsm &);
   static tree asm_construct_outputs (HIR::InlineAsm &);
diff --git a/gcc/rust/backend/rust-compile-expr.cc 
b/gcc/rust/backend/rust-compile-expr.cc
index 064be6ee81f..b59ed4183e7 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -321,6 +321,7 @@ CompileExpr::visit (HIR::IfExpr &expr)
 void
 CompileExpr::visit (HIR::InlineAsm &expr)
 {
+  translated = CompileAsm::asm_build_expr (expr);
   // translated = build_asm_expr (0, NULL_TREE, NULL_TREE, NULL_TREE, 
NULL_TREE,
   //                  NULL_TREE, true, true);
   // CompileAsm::asm_build_expr (expr);
-- 
2.45.2

Reply via email to