aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorbadumbatish <tanghocle456@gmail.com>2024-07-07 22:03:12 -0700
committerCohenArthur <arthur.cohen@embecosm.com>2024-09-02 09:44:55 +0000
commit63bccfc7f19f95b198d1436630118c8f9473ba1b (patch)
tree6db519600ad6301569067aa0e891f28533b28eb4 /gcc
parentf627811f55b3258c3be1813ad71babac262d7387 (diff)
downloadgcc-63bccfc7f19f95b198d1436630118c8f9473ba1b.zip
gcc-63bccfc7f19f95b198d1436630118c8f9473ba1b.tar.gz
gcc-63bccfc7f19f95b198d1436630118c8f9473ba1b.tar.bz2
Refactor compile-asm for first round review
gcc/rust/ChangeLog: * backend/rust-compile-asm.cc (strip_double_quotes): Refactor compile-asm for first round review (CompileAsm::asm_build_asm_stmt): Likewise. (CompileAsm::asm_build_expr): Likewise. (CompileAsm::asm_get_locus): Likewise. (CompileAsm::asm_construct_string_tree): Likewise. (CompileAsm::asm_construct_outputs): Likewise. (CompileAsm::asm_construct_inputs): Likewise. (CompileAsm::asm_construct_clobber_tree): Likewise. (CompileAsm::asm_construct_label_tree): Likewise. (CompileAsm::asm_is_simple): Likewise. (CompileAsm::asm_is_inline): Likewise. * backend/rust-compile-asm.h (strip_double_quotes): Likewise. (class CompileAsm): Likewise.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/backend/rust-compile-asm.cc251
-rw-r--r--gcc/rust/backend/rust-compile-asm.h127
2 files changed, 107 insertions, 271 deletions
diff --git a/gcc/rust/backend/rust-compile-asm.cc b/gcc/rust/backend/rust-compile-asm.cc
index 66e265f..6e4d9f6 100644
--- a/gcc/rust/backend/rust-compile-asm.cc
+++ b/gcc/rust/backend/rust-compile-asm.cc
@@ -1,72 +1,57 @@
#include "rust-compile-asm.h"
-#include "rust-tree.h"
#include "rust-system.h"
-#include <cstddef>
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)
{
- return ctx->add_statement (asm_build_expr (expr));
-}
-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 NULL_TREE;
+ ctx->add_statement (asm_build_expr (expr));
}
+
tree
CompileAsm::asm_build_expr (HIR::InlineAsm &expr)
{
- 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)});
+ 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) = CompileAsm::asm_is_simple (expr);
- ASM_VOLATILE_P (asm_expr) = (false);
+ 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),
- // CompileAsm::asm_construct_inputs (expr),
- // CompileAsm::asm_construct_clobber_tree (expr),
- // CompileAsm::asm_construct_label_tree (expr),
- // CompileAsm::asm_is_simple (expr),
- // CompileAsm::asm_is_inline (expr));
}
tree
CompileAsm::asm_build_stmt (
- location_t loc, enum tree_code code,
+ location_t loc,
const std::array<tree, CompileAsm::ASM_TREE_ARRAY_LENGTH> &trees)
{
+ // Prototype functiion for building an ASM_EXPR tree.
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);
+ ret = make_node (ASM_EXPR);
TREE_TYPE (ret) = void_type_node;
SET_EXPR_LOCATION (ret, loc);
@@ -75,6 +60,8 @@ CompileAsm::asm_build_stmt (
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++)
{
@@ -86,213 +73,65 @@ CompileAsm::asm_build_stmt (
TREE_SIDE_EFFECTS (ret) |= side_effects;
- // va_end (p);
return ret;
}
-location_t
-CompileAsm::asm_get_locus (HIR::InlineAsm &expr)
-{
- return expr.get_locus ();
-}
+
tree
CompileAsm::asm_construct_string_tree (HIR::InlineAsm &expr)
{
- if (expr.template_strs.empty ())
- return build_string (1, "");
- else
- return build_string (4, "nop");
- // Initialize to NULL_TREE
- tree string_chain = NULL_TREE;
-
+ // 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)
- {
- auto str = template_str.symbol;
- auto string_tree = build_string (str.size () + 1, str.c_str ());
-
- string_chain = tree_cons (NULL_TREE, string_tree, string_chain);
- }
- // Reverse the chain before returning
+ ss << strip_double_quotes (template_str.symbol) << "\n\t";
- string_chain = nreverse (string_chain);
-
- return nreverse (string_chain);
+ 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;
}
bool
CompileAsm::asm_is_simple (HIR::InlineAsm &expr)
{
+ // TODO: Check back later to determine how an InlineAsm is simple.
return true;
}
bool
CompileAsm::asm_is_inline (HIR::InlineAsm &expr)
{
+ // TODO: Check back later to determine how an InlineAsm is inline.
return true;
}
} // namespace Compile
} // namespace Rust
- //
- //
- // The following section serves as documentation for PR revieweres and future
- // asm developers. It documents the inspriation for the implementation of the
- // CompileAsm class
-
-// 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);
-// }
-//
-///* Build an asm-expr, whose components are a STRING, some OUTPUTS,
-// some INPUTS, and some CLOBBERS. The latter three may be NULL.
-// SIMPLE indicates whether there was anything at all after the
-// string in the asm expression -- asm("blah") and asm("blah" : )
-// are subtly different. We use a ASM_EXPR node to represent this.
-// LOC is the location of the asm, and IS_INLINE says whether this
-// is asm inline. */
-// tree
-// build_asm_expr (location_t loc, tree string, tree outputs, tree inputs,
-// tree clobbers, tree labels, bool simple, bool is_inline)
-//{
-// tree tail;
-// tree args;
-// int i;
-// const char *constraint;
-// const char **oconstraints;
-// bool allows_mem, allows_reg, is_inout;
-// int ninputs, noutputs;
-//
-// ninputs = list_length (inputs);
-// noutputs = list_length (outputs);
-// oconstraints = (const char **) alloca (noutputs * sizeof (const char *));
-//
-// string = resolve_asm_operand_names (string, outputs, inputs, labels);
-//
-// /* Remove output conversions that change the type but not the mode. */
-// for (i = 0, tail = outputs; tail; ++i, tail = TREE_CHAIN (tail))
-// {
-// tree output = TREE_VALUE (tail);
-//
-// output = c_fully_fold (output, false, NULL, true);
-//
-// /* ??? Really, this should not be here. Users should be using a
-// proper lvalue, dammit. But there's a long history of using casts
-// in the output operands. In cases like longlong.h, this becomes a
-// primitive form of typechecking -- if the cast can be removed, then
-// the output operand had a type of the proper width; otherwise we'll
-// get an error. Gross, but ... */
-// STRIP_NOPS (output);
-//
-// if (!lvalue_or_else (loc, output, lv_asm))
-// output = error_mark_node;
-//
-// if (output != error_mark_node
-// && (TREE_READONLY (output)
-// || TYPE_READONLY (TREE_TYPE (output))
-// || (RECORD_OR_UNION_TYPE_P (TREE_TYPE (output))
-// && C_TYPE_FIELDS_READONLY (TREE_TYPE (output)))))
-// readonly_error (loc, output, lv_asm);
-//
-// constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (tail)));
-// oconstraints[i] = constraint;
-//
-// if (parse_output_constraint (&constraint, i, ninputs, noutputs,
-// &allows_mem, &allows_reg, &is_inout))
-// {
-// /* If the operand is going to end up in memory,
-// mark it addressable. */
-// if (!allows_reg && !c_mark_addressable (output))
-// output = error_mark_node;
-// if (!(!allows_reg && allows_mem)
-// && output != error_mark_node
-// && VOID_TYPE_P (TREE_TYPE (output)))
-// {
-// error_at (loc, "invalid use of void expression");
-// output = error_mark_node;
-// }
-// }
-// else
-// output = error_mark_node;
-//
-// TREE_VALUE (tail) = output;
-// }
-//
-// for (i = 0, tail = inputs; tail; ++i, tail = TREE_CHAIN (tail))
-// {
-// tree input;
-//
-// constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (tail)));
-// input = TREE_VALUE (tail);
-//
-// if (parse_input_constraint (&constraint, i, ninputs, noutputs, 0,
-// oconstraints, &allows_mem, &allows_reg))
-// {
-// /* If the operand is going to end up in memory,
-// mark it addressable. */
-// if (!allows_reg && allows_mem)
-// {
-// input = c_fully_fold (input, false, NULL, true);
-//
-// /* Strip the nops as we allow this case. FIXME, this really
-// should be rejected or made deprecated. */
-// STRIP_NOPS (input);
-// if (!c_mark_addressable (input))
-// input = error_mark_node;
-// }
-// else
-// {
-// struct c_expr expr;
-// memset (&expr, 0, sizeof (expr));
-// expr.value = input;
-// expr = convert_lvalue_to_rvalue (loc, expr, true, false);
-// input = c_fully_fold (expr.value, false, NULL);
-//
-// if (input != error_mark_node && VOID_TYPE_P (TREE_TYPE (input)))
-// {
-// error_at (loc, "invalid use of void expression");
-// input = error_mark_node;
-// }
-// }
-// }
-// else
-// input = error_mark_node;
-//
-// TREE_VALUE (tail) = input;
-// }
-//
-// args = build_stmt (loc, ASM_EXPR, string, outputs, inputs, clobbers,
-// labels);
-//
-// /* asm statements without outputs, including simple ones, are treated
-// as volatile. */
-// ASM_INPUT_P (args) = simple;
-// ASM_VOLATILE_P (args) = (noutputs == 0);
-// ASM_INLINE_P (args) = is_inline;
-//
-// return args;
-//}
diff --git a/gcc/rust/backend/rust-compile-asm.h b/gcc/rust/backend/rust-compile-asm.h
index d7967bc..15ffc70 100644
--- a/gcc/rust/backend/rust-compile-asm.h
+++ b/gcc/rust/backend/rust-compile-asm.h
@@ -26,78 +26,25 @@
namespace Rust {
namespace Compile {
+std::string
+strip_double_quotes (const std::string &);
+
class CompileAsm : private HIRCompileBase, protected HIR::HIRExpressionVisitor
{
+private:
+ tree translated;
+
public:
+ // WE WILL OPEN THIS UP WHEN WE WANT TO ADD A DEDICATED PASS OF HIR'S ASM
+ // translation.
// static tree Compile (HIR::Expr *expr, Context *ctx);
- void visit (HIR::InlineAsm &expr) override;
-
- void visit (HIR::TupleIndexExpr &expr) override {}
- void visit (HIR::TupleExpr &expr) override {}
- void visit (HIR::ReturnExpr &expr) override {}
- void visit (HIR::CallExpr &expr) override {}
- void visit (HIR::MethodCallExpr &expr) override {}
- void visit (HIR::LiteralExpr &expr) override {}
- void visit (HIR::AssignmentExpr &expr) override {}
- void visit (HIR::CompoundAssignmentExpr &expr) override {}
- void visit (HIR::ArrayIndexExpr &expr) override {}
- void visit (HIR::ArrayExpr &expr) override {}
- void visit (HIR::ArithmeticOrLogicalExpr &expr) override {}
- void visit (HIR::ComparisonExpr &expr) override {}
- void visit (HIR::LazyBooleanExpr &expr) override {}
- void visit (HIR::NegationExpr &expr) override {}
- void visit (HIR::TypeCastExpr &expr) override {}
- void visit (HIR::IfExpr &expr) override {}
- void visit (HIR::IfExprConseqElse &expr) override {}
- void visit (HIR::BlockExpr &expr) override {}
- void visit (HIR::UnsafeBlockExpr &expr) override {}
- void visit (HIR::StructExprStruct &struct_expr) override {}
- void visit (HIR::StructExprStructFields &struct_expr) override {}
- void visit (HIR::GroupedExpr &expr) override {}
- void visit (HIR::FieldAccessExpr &expr) override {}
- void visit (HIR::QualifiedPathInExpression &expr) override {}
- void visit (HIR::PathInExpression &expr) override {}
- void visit (HIR::LoopExpr &expr) override {}
- void visit (HIR::WhileLoopExpr &expr) override {}
- void visit (HIR::BreakExpr &expr) override {}
- void visit (HIR::ContinueExpr &expr) override {}
- void visit (HIR::BorrowExpr &expr) override {}
- void visit (HIR::DereferenceExpr &expr) override {}
- void visit (HIR::MatchExpr &expr) override {}
- void visit (HIR::RangeFromToExpr &expr) override {}
- void visit (HIR::RangeFromExpr &expr) override {}
- void visit (HIR::RangeToExpr &expr) override {}
- void visit (HIR::RangeFullExpr &expr) override {}
- void visit (HIR::RangeFromToInclExpr &expr) override {}
- void visit (HIR::ClosureExpr &expr) override {}
-
- // TODO
- void visit (HIR::ErrorPropagationExpr &) override {}
- void visit (HIR::RangeToInclExpr &) override {}
-
- // TODO
- // these need to be sugared in the HIR to if statements and a match
- void visit (HIR::WhileLetLoopExpr &) override {}
- void visit (HIR::IfLetExpr &) override {}
- void visit (HIR::IfLetExprConseqElse &) override {}
-
- // lets not worry about async yet....
- void visit (HIR::AwaitExpr &) override {}
- void visit (HIR::AsyncBlockExpr &) override {}
-
- // nothing to do for these
- void visit (HIR::StructExprFieldIdentifier &) override {}
- void visit (HIR::StructExprFieldIdentifierValue &) override {}
- void visit (HIR::StructExprFieldIndexValue &) override {}
-
+ // RELEVANT MEMBER FUNCTIONS
static const int ASM_TREE_ARRAY_LENGTH = 5;
- 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,
+ static tree asm_build_stmt (location_t,
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 &);
static tree asm_construct_inputs (HIR::InlineAsm &);
@@ -108,8 +55,58 @@ public:
CompileAsm (Context *ctx);
-private:
- tree translated;
+ void visit (HIR::InlineAsm &) override;
+
+ // NON RELEVANT MEMBER FUNCTIONS
+
+ void visit (HIR::TupleIndexExpr &) override {}
+ void visit (HIR::TupleExpr &) override {}
+ void visit (HIR::ReturnExpr &) override {}
+ void visit (HIR::CallExpr &) override {}
+ void visit (HIR::MethodCallExpr &) override {}
+ void visit (HIR::LiteralExpr &) override {}
+ void visit (HIR::AssignmentExpr &) override {}
+ void visit (HIR::CompoundAssignmentExpr &) override {}
+ void visit (HIR::ArrayIndexExpr &) override {}
+ void visit (HIR::ArrayExpr &) override {}
+ void visit (HIR::ArithmeticOrLogicalExpr &) override {}
+ void visit (HIR::ComparisonExpr &) override {}
+ void visit (HIR::LazyBooleanExpr &) override {}
+ void visit (HIR::NegationExpr &) override {}
+ void visit (HIR::TypeCastExpr &) override {}
+ void visit (HIR::IfExpr &) override {}
+ void visit (HIR::IfExprConseqElse &) override {}
+ void visit (HIR::BlockExpr &) override {}
+ void visit (HIR::UnsafeBlockExpr &) override {}
+ void visit (HIR::StructExprStruct &struct_) override {}
+ void visit (HIR::StructExprStructFields &struct_) override {}
+ void visit (HIR::GroupedExpr &) override {}
+ void visit (HIR::FieldAccessExpr &) override {}
+ void visit (HIR::QualifiedPathInExpression &) override {}
+ void visit (HIR::PathInExpression &) override {}
+ void visit (HIR::LoopExpr &) override {}
+ void visit (HIR::WhileLoopExpr &) override {}
+ void visit (HIR::BreakExpr &) override {}
+ void visit (HIR::ContinueExpr &) override {}
+ void visit (HIR::BorrowExpr &) override {}
+ void visit (HIR::DereferenceExpr &) override {}
+ void visit (HIR::MatchExpr &) override {}
+ void visit (HIR::RangeFromToExpr &) override {}
+ void visit (HIR::RangeFromExpr &) override {}
+ void visit (HIR::RangeToExpr &) override {}
+ void visit (HIR::RangeFullExpr &) override {}
+ void visit (HIR::RangeFromToInclExpr &) override {}
+ void visit (HIR::ClosureExpr &) override {}
+ void visit (HIR::ErrorPropagationExpr &) override {}
+ void visit (HIR::RangeToInclExpr &) override {}
+ void visit (HIR::WhileLetLoopExpr &) override {}
+ void visit (HIR::IfLetExpr &) override {}
+ void visit (HIR::IfLetExprConseqElse &) override {}
+ void visit (HIR::AwaitExpr &) override {}
+ void visit (HIR::AsyncBlockExpr &) override {}
+ void visit (HIR::StructExprFieldIdentifier &) override {}
+ void visit (HIR::StructExprFieldIdentifierValue &) override {}
+ void visit (HIR::StructExprFieldIndexValue &) override {}
};
} // namespace Compile
} // namespace Rust