aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/backend/rust-compile-asm.cc
blob: 301da4001254d420ff1a38b37a663233c884b4b1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include "rust-compile-asm.h"

#include "rust-system.h"
namespace Rust {
namespace Compile {

std::string
strip_double_quotes (const std::string &str)
{
  // Helper function strips the beginning and ending double quotes from a
  // string.
  std::string result = str;

  rust_assert (result.size () >= 3);
  result.erase (0, 1);
  result.erase (result.size () - 1, 1);
  return result;
}

CompileAsm::CompileAsm (Context *ctx)
  : HIRCompileBase (ctx), translated (error_mark_node)
{}
void
CompileAsm::visit (HIR::InlineAsm &expr)
{
  ctx->add_statement (asm_build_expr (expr));
}

tree
CompileAsm::asm_build_expr (HIR::InlineAsm &expr)
{
  auto asm_expr
    = asm_build_stmt (expr.get_locus (), {asm_construct_string_tree (expr),
					  asm_construct_outputs (expr),
					  asm_construct_inputs (expr),
					  asm_construct_clobber_tree (expr),
					  asm_construct_label_tree (expr)});

  ASM_INPUT_P (asm_expr) = expr.is_simple_asm ();
  ASM_VOLATILE_P (asm_expr) = false;
  ASM_INLINE_P (asm_expr) = expr.is_inline_asm ();
  return asm_expr;
}

tree
CompileAsm::asm_build_stmt (
  location_t loc,
  const std::array<tree, CompileAsm::ASM_TREE_ARRAY_LENGTH> &trees)
{
  // Prototype functiion for building an ASM_EXPR tree.
  tree ret;
  bool side_effects;

  ret = make_node (ASM_EXPR);
  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.  */

  // This is here because of c-typeck.cc's code
  // I'm not sure what kind of effects it has
  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;

  return ret;
}

tree
CompileAsm::asm_construct_string_tree (HIR::InlineAsm &expr)
{
  // To construct an ASM_EXPR tree, we need to build a STRING_CST tree.
  //
  // We do this by concatenating all the template strings in the InlineAsm
  // into one big std::string seperated by tabs and newlines. (For easier
  // debugging and reading)
  std::stringstream ss;
  for (const auto &template_str : expr.template_strs)
    ss << strip_double_quotes (template_str.symbol) << "\n\t";

  std::string result = ss.str ();
  return build_string (result.size () + 1, result.c_str ());
}

tree
CompileAsm::asm_construct_outputs (HIR::InlineAsm &expr)
{
  // TODO: Do i need to do this?
  return NULL_TREE;
}

tree
CompileAsm::asm_construct_inputs (HIR::InlineAsm &expr)
{
  // TODO: Do i need to do this?
  return NULL_TREE;
}

tree
CompileAsm::asm_construct_clobber_tree (HIR::InlineAsm &expr)
{
  // TODO: Do i need to do this?
  return NULL_TREE;
}

tree
CompileAsm::asm_construct_label_tree (HIR::InlineAsm &expr)
{
  // TODO: Do i need to do this?
  return NULL_TREE;
}

} // namespace Compile
} // namespace Rust