From: badumbatish <tanghocle...@gmail.com> gcc/rust/ChangeLog:
* hir/rust-ast-lower-expr.cc (from_operand): Set up the lowering for operand (ASTLoweringExpr::visit): Likewise * hir/tree/rust-hir-expr.h (struct InlineAsmRegOrRegClass): Not necessary, kept from ast (struct AnonConst): Set up lowering for operand (class InlineAsmOperand): Likewise, add getters --- gcc/rust/hir/rust-ast-lower-expr.cc | 100 ++++++++++- gcc/rust/hir/tree/rust-hir-expr.h | 257 ++++++++++++++++++++++++++-- 2 files changed, 343 insertions(+), 14 deletions(-) diff --git a/gcc/rust/hir/rust-ast-lower-expr.cc b/gcc/rust/hir/rust-ast-lower-expr.cc index be7ff413c93..45277e87714 100644 --- a/gcc/rust/hir/rust-ast-lower-expr.cc +++ b/gcc/rust/hir/rust-ast-lower-expr.cc @@ -829,6 +829,92 @@ ASTLoweringExpr::visit (AST::ClosureExprInnerTyped &expr) expr.get_locus ()); } +HIR::InlineAsmOperand +from_operand (const AST::InlineAsmOperand &operand) +{ + using RegisterType = AST::InlineAsmOperand::RegisterType; + using Operand = HIR::InlineAsmOperand; + auto type = operand.get_register_type (); + + /*In,*/ + /*Out,*/ + /*InOut,*/ + /*SplitInOut,*/ + /*Const,*/ + /*Sym,*/ + /*Label,*/ + if (type == RegisterType::In) + { + auto in_value = operand.get_in (); + + struct Operand::In in (in_value.reg, + std::unique_ptr<Expr> (ASTLoweringExpr::translate ( + *in_value.expr.get ()))); + return in; + } + else if (type == RegisterType::Out) + { + auto out_value = operand.get_out (); + struct Operand::Out out (out_value.reg, out_value.late, + std::unique_ptr<Expr> ( + ASTLoweringExpr::translate ( + *out_value.expr.get ()))); + return out; + } + else if (type == RegisterType::InOut) + { + auto inout_value = operand.get_in_out (); + struct Operand::InOut inout (inout_value.reg, inout_value.late, + std::unique_ptr<Expr> ( + ASTLoweringExpr::translate ( + *inout_value.expr.get ()))); + return inout; + } + else if (type == RegisterType::SplitInOut) + { + auto split_in_out_value = operand.get_split_in_out (); + struct Operand::SplitInOut split_in_out ( + split_in_out_value.reg, split_in_out_value.late, + std::unique_ptr<Expr> ( + ASTLoweringExpr::translate (*split_in_out_value.in_expr.get ())), + std::unique_ptr<Expr> ( + ASTLoweringExpr::translate (*split_in_out_value.out_expr.get ()))); + return split_in_out; + } + else if (type == RegisterType::Const) + { + auto const_value = operand.get_const (); + struct HIR::AnonConst anon_const ( + const_value.anon_const.id, + std::unique_ptr<Expr> ( + ASTLoweringExpr::translate (*const_value.anon_const.expr.get ()))); + struct Operand::Const cnst + { + anon_const + }; + return cnst; + } + else if (type == RegisterType::Sym) + { + auto sym_value = operand.get_sym (); + struct Operand::Sym sym (std::unique_ptr<Expr> ( + ASTLoweringExpr::translate (*sym_value.expr.get ()))); + return sym; + } + else if (type == RegisterType::Label) + { + auto label_value = operand.get_label (); + struct Operand::Label label (label_value.label_name, + std::unique_ptr<Expr> ( + ASTLoweringExpr::translate ( + *label_value.expr.get ()))); + return label; + } + else + { + rust_unreachable (); + } +} void ASTLoweringExpr::visit (AST::InlineAsm &expr) { @@ -837,10 +923,22 @@ ASTLoweringExpr::visit (AST::InlineAsm &expr) mappings.get_next_hir_id (crate_num), mappings.get_next_localdef_id (crate_num)); + std::vector<HIR::InlineAsmOperand> hir_operands; + std::vector<AST::InlineAsmOperand> ast_operands = expr.get_operands (); + /*int ast_operands_size = ast_operands.size ();*/ + for (auto &operand : ast_operands) + { + hir_operands.push_back (from_operand (operand)); + } + /*int hir_operands_size = hir_operands.size ();*/ + + /*rust_debug ("{bdbt} : There are %d ast operands prelowering and %d hir "*/ + /* "operands after lowering\n",*/ + /* ast_operands_size, hir_operands_size);*/ translated = new HIR::InlineAsm (expr.get_locus (), expr.is_global_asm, expr.get_template_ (), expr.get_template_strs (), - expr.get_operands (), expr.get_clobber_abi (), + hir_operands, expr.get_clobber_abi (), expr.get_options (), mapping); } void diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h index ff9fcee1a46..5d2cdd1814a 100644 --- a/gcc/rust/hir/tree/rust-hir-expr.h +++ b/gcc/rust/hir/tree/rust-hir-expr.h @@ -3843,28 +3843,259 @@ class InlineAsmRegClass std::string placeholder; }; -struct InlineAsmRegOrRegClass +struct AnonConst { - enum Type + NodeId id; + std::unique_ptr<Expr> expr; + AnonConst (NodeId id, std::unique_ptr<Expr> expr) + : id (id), expr (std::move (expr)) + { + rust_assert (this->expr != nullptr); + } + AnonConst (const AnonConst &other) + { + id = other.id; + expr = other.expr->clone_expr (); + } + + AnonConst operator= (const AnonConst &other) + { + id = other.id; + expr = other.expr->clone_expr (); + return *this; + } +}; +; + +class InlineAsmOperand +{ +public: + struct In { - Reg, // links to struct Register - RegClass, // links to struct RegisterClass + tl::optional<struct AST::InlineAsmRegOrRegClass> reg; + std::unique_ptr<Expr> expr; + + In (const tl::optional<struct AST::InlineAsmRegOrRegClass> ®, + std::unique_ptr<Expr> expr) + : reg (reg), expr (std::move (expr)) + { + rust_assert (this->expr != nullptr); + } + + In (const struct In &other) + { + reg = other.reg; + + expr = other.expr->clone_expr (); + } + + In operator= (const struct In &other) + { + reg = other.reg; + expr = other.expr->clone_expr (); + + return *this; + } }; - struct Register + struct Out { - InlineAsmReg Reg; + tl::optional<struct AST::InlineAsmRegOrRegClass> reg; + bool late; + std::unique_ptr<Expr> expr; // can be null + + Out (tl::optional<struct AST::InlineAsmRegOrRegClass> ®, bool late, + std::unique_ptr<Expr> expr) + : reg (reg), late (late), expr (std::move (expr)) + { + rust_assert (this->expr != nullptr); + } + + Out (const struct Out &other) + { + reg = other.reg; + late = other.late; + expr = other.expr->clone_expr (); + } + + Out operator= (const struct Out &other) + { + reg = other.reg; + late = other.late; + expr = other.expr->clone_expr (); + return *this; + } }; - struct RegisterClass + struct InOut { - InlineAsmRegClass RegClass; + tl::optional<struct AST::InlineAsmRegOrRegClass> reg; + bool late; + std::unique_ptr<Expr> expr; // this can't be null + + InOut (tl::optional<struct AST::InlineAsmRegOrRegClass> ®, bool late, + std::unique_ptr<Expr> expr) + : reg (reg), late (late), expr (std::move (expr)) + { + rust_assert (this->expr != nullptr); + } + + InOut (const struct InOut &other) + { + reg = other.reg; + late = other.late; + expr = other.expr->clone_expr (); + } + + InOut operator= (const struct InOut &other) + { + reg = other.reg; + late = other.late; + expr = other.expr->clone_expr (); + + return *this; + } + }; + + struct SplitInOut + { + tl::optional<struct AST::InlineAsmRegOrRegClass> reg; + bool late; + std::unique_ptr<Expr> in_expr; + std::unique_ptr<Expr> out_expr; // could be null + + SplitInOut (tl::optional<struct AST::InlineAsmRegOrRegClass> ®, + bool late, std::unique_ptr<Expr> in_expr, + std::unique_ptr<Expr> out_expr) + : reg (reg), late (late), in_expr (std::move (in_expr)), + out_expr (std::move (out_expr)) + { + rust_assert (this->in_expr != nullptr); + rust_assert (this->out_expr != nullptr); + } + + SplitInOut (const struct SplitInOut &other) + { + reg = other.reg; + late = other.late; + in_expr = other.in_expr->clone_expr (); + out_expr = other.out_expr->clone_expr (); + } + + SplitInOut operator= (const struct SplitInOut &other) + { + reg = other.reg; + late = other.late; + in_expr = other.in_expr->clone_expr (); + out_expr = other.out_expr->clone_expr (); + + return *this; + } + }; + + struct Const + { + AnonConst anon_const; }; - Identifier name; + struct Sym + { + std::unique_ptr<Expr> expr; + + Sym (std::unique_ptr<Expr> expr) : expr (std::move (expr)) + { + rust_assert (this->expr != nullptr); + } + Sym (const struct Sym &other) + { + expr = std::unique_ptr<Expr> (other.expr->clone_expr ()); + } + + Sym operator= (const struct Sym &other) + { + expr = std::unique_ptr<Expr> (other.expr->clone_expr ()); + return *this; + } + }; + + struct Label + { + std::string label_name; + std::unique_ptr<Expr> expr; + + Label (tl::optional<std::string> label_name, std::unique_ptr<Expr> expr) + : expr (std::move (expr)) + { + rust_assert (this->expr != nullptr); + if (label_name.has_value ()) + this->label_name = label_name.value (); + } + Label (const struct Label &other) + { + expr = std::unique_ptr<Expr> (other.expr->clone_expr ()); + } + + Label operator= (const struct Label &other) + { + expr = std::unique_ptr<Expr> (other.expr->clone_expr ()); + return *this; + } + }; + +private: + using RegisterType = AST::InlineAsmOperand::RegisterType; + AST::InlineAsmOperand::RegisterType register_type; + + tl::optional<struct In> in; + tl::optional<struct Out> out; + tl::optional<struct InOut> in_out; + tl::optional<struct SplitInOut> split_in_out; + tl::optional<struct Const> cnst; + tl::optional<struct Sym> sym; + tl::optional<struct Label> label; location_t locus; -}; +public: + InlineAsmOperand (const InlineAsmOperand &other) + : register_type (other.register_type), in (other.in), out (other.out), + in_out (other.in_out), split_in_out (other.split_in_out), + cnst (other.cnst), sym (other.sym) + {} + + InlineAsmOperand (const struct In ®) + : register_type (RegisterType::In), in (reg) + {} + + InlineAsmOperand (const struct Out ®) + : register_type (RegisterType::Out), out (reg) + {} + InlineAsmOperand (const struct InOut ®) + : register_type (RegisterType::InOut), in_out (reg) + {} + InlineAsmOperand (const struct SplitInOut ®) + : register_type (RegisterType::SplitInOut), split_in_out (reg) + {} + InlineAsmOperand (const struct Const ®) + : register_type (RegisterType::Const), cnst (reg) + {} + InlineAsmOperand (const struct Sym ®) + : register_type (RegisterType::Sym), sym (reg) + {} + InlineAsmOperand (const struct Label ®) + : register_type (RegisterType::Label), label (reg) + {} + + RegisterType get_register_type () const { return register_type; } + + // Potentially unsafe without get_register_type() check + struct In get_in () const { return in.value (); } + struct Out get_out () const { return out.value (); } + struct InOut get_in_out () const { return in_out.value (); } + struct SplitInOut get_split_in_out () const { return split_in_out.value (); } + struct Const get_const () const { return cnst.value (); } + struct Sym get_sym () const { return sym.value (); } + struct Label get_label () const { return label.value (); } +}; // Inline Assembly Node class InlineAsm : public ExprWithoutBlock { @@ -3876,7 +4107,7 @@ public: std::vector<AST::InlineAsmTemplatePiece> template_; std::vector<AST::TupleTemplateStr> template_strs; - std::vector<AST::InlineAsmOperand> operands; + std::vector<HIR::InlineAsmOperand> operands; std::vector<AST::TupleClobber> clobber_abi; std::set<AST::InlineAsmOption> options; @@ -3909,7 +4140,7 @@ public: return template_strs; } - std::vector<AST::InlineAsmOperand> get_operands () { return operands; } + std::vector<HIR::InlineAsmOperand> get_operands () { return operands; } std::vector<AST::TupleClobber> get_clobber_abi () { return clobber_abi; } @@ -3918,7 +4149,7 @@ public: InlineAsm (location_t locus, bool is_global_asm, std::vector<AST::InlineAsmTemplatePiece> template_, std::vector<AST::TupleTemplateStr> template_strs, - std::vector<AST::InlineAsmOperand> operands, + std::vector<HIR::InlineAsmOperand> operands, std::vector<AST::TupleClobber> clobber_abi, std::set<AST::InlineAsmOption> options, Analysis::NodeMapping mappings, -- 2.45.2