Skip to content

Commit d4676fb

Browse files
P-E-PCohenArthur
authored andcommitted
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 <[email protected]>
1 parent 58cef6b commit d4676fb

File tree

1 file changed

+71
-34
lines changed

1 file changed

+71
-34
lines changed

gcc/rust/backend/rust-compile-asm.cc

Lines changed: 71 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -74,57 +74,94 @@ CompileAsm::asm_construct_string_tree (HIR::InlineAsm &expr)
7474
return Backend::string_constant_expression (result);
7575
}
7676

77+
tl::optional<std::reference_wrapper<HIR::Expr>>
78+
get_out_expr (HIR::InlineAsmOperand &operand)
79+
{
80+
switch (operand.get_register_type ())
81+
{
82+
case HIR::InlineAsmOperand::RegisterType::Out:
83+
return *operand.get_out ().expr;
84+
case HIR::InlineAsmOperand::RegisterType::InOut:
85+
return *operand.get_in_out ().expr;
86+
case HIR::InlineAsmOperand::RegisterType::SplitInOut:
87+
return *operand.get_split_in_out ().out_expr;
88+
case HIR::InlineAsmOperand::RegisterType::Const:
89+
case HIR::InlineAsmOperand::RegisterType::Sym:
90+
case HIR::InlineAsmOperand::RegisterType::Label:
91+
case HIR::InlineAsmOperand::RegisterType::In:
92+
break;
93+
}
94+
return tl::nullopt;
95+
}
96+
7797
tree
7898
CompileAsm::asm_construct_outputs (HIR::InlineAsm &expr)
7999
{
80100
// TODO: Do i need to do this?
81101

82102
tree head = NULL_TREE;
83-
for (auto &output : expr.get_operands ())
103+
for (auto &operand : expr.get_operands ())
84104
{
85-
if (output.get_register_type ()
86-
== AST::InlineAsmOperand::RegisterType::Out)
87-
{
88-
auto out = output.get_out ();
89-
90-
tree out_tree = CompileExpr::Compile (*out.expr, this->ctx);
91-
// expects a tree list
92-
// TODO: This assumes that the output is a register
93-
std::string expr_name = "=r";
94-
auto name = build_string (expr_name.size () + 1, expr_name.c_str ());
95-
head
96-
= chainon (head, build_tree_list (build_tree_list (NULL_TREE, name),
97-
out_tree));
98-
99-
/*Backend::debug (head);*/
100-
/*head = chainon (head, out_tree);*/
101-
}
105+
tl::optional<std::reference_wrapper<HIR::Expr>> out_expr
106+
= get_out_expr (operand);
107+
if (!out_expr.has_value ())
108+
continue;
109+
110+
tree out_tree = CompileExpr::Compile (*out_expr, this->ctx);
111+
// expects a tree list
112+
// TODO: This assumes that the output is a register
113+
std::string expr_name = "=r";
114+
auto name = build_string (expr_name.size () + 1, expr_name.c_str ());
115+
head = chainon (head, build_tree_list (build_tree_list (NULL_TREE, name),
116+
out_tree));
117+
118+
/*Backend::debug (head);*/
119+
/*head = chainon (head, out_tree);*/
102120
}
103121
return head;
104122
}
105123

124+
tl::optional<std::reference_wrapper<HIR::Expr>>
125+
get_in_expr (HIR::InlineAsmOperand &operand)
126+
{
127+
switch (operand.get_register_type ())
128+
{
129+
case HIR::InlineAsmOperand::RegisterType::In:
130+
return *operand.get_in ().expr;
131+
case HIR::InlineAsmOperand::RegisterType::InOut:
132+
return *operand.get_in_out ().expr;
133+
case HIR::InlineAsmOperand::RegisterType::SplitInOut:
134+
return *operand.get_split_in_out ().in_expr;
135+
case HIR::InlineAsmOperand::RegisterType::Const:
136+
case HIR::InlineAsmOperand::RegisterType::Sym:
137+
case HIR::InlineAsmOperand::RegisterType::Label:
138+
case HIR::InlineAsmOperand::RegisterType::Out:
139+
break;
140+
}
141+
return tl::nullopt;
142+
}
143+
106144
tree
107145
CompileAsm::asm_construct_inputs (HIR::InlineAsm &expr)
108146
{
109147
// TODO: Do i need to do this?
110148
tree head = NULL_TREE;
111-
for (auto &input : expr.get_operands ())
149+
for (auto &operand : expr.get_operands ())
112150
{
113-
if (input.get_register_type () == AST::InlineAsmOperand::RegisterType::In)
114-
{
115-
auto in = input.get_in ();
116-
117-
tree in_tree = CompileExpr::Compile (*in.expr, this->ctx);
118-
// expects a tree list
119-
// TODO: This assumes that the input is a register
120-
std::string expr_name = "r";
121-
auto name = build_string (expr_name.size () + 1, expr_name.c_str ());
122-
head
123-
= chainon (head, build_tree_list (build_tree_list (NULL_TREE, name),
124-
in_tree));
125-
126-
/*head = chainon (head, out_tree);*/
127-
}
151+
tl::optional<std::reference_wrapper<HIR::Expr>> in_expr
152+
= get_in_expr (operand);
153+
if (!in_expr.has_value ())
154+
continue;
155+
156+
tree in_tree = CompileExpr::Compile (*in_expr, this->ctx);
157+
// expects a tree list
158+
// TODO: This assumes that the input is a register
159+
std::string expr_name = "r";
160+
auto name = build_string (expr_name.size () + 1, expr_name.c_str ());
161+
head = chainon (head, build_tree_list (build_tree_list (NULL_TREE, name),
162+
in_tree));
163+
164+
/*head = chainon (head, out_tree);*/
128165
}
129166
return head;
130167
}

0 commit comments

Comments
 (0)