diff options
-rw-r--r-- | src/hir/deserialise.cpp | 8 | ||||
-rw-r--r-- | src/hir/serialise.cpp | 8 | ||||
-rw-r--r-- | src/mir/check.cpp | 21 | ||||
-rw-r--r-- | src/mir/cleanup.cpp | 6 | ||||
-rw-r--r-- | src/mir/dump.cpp | 16 | ||||
-rw-r--r-- | src/mir/from_hir.cpp | 17 | ||||
-rw-r--r-- | src/mir/from_hir.hpp | 2 | ||||
-rw-r--r-- | src/mir/mir.hpp | 16 | ||||
-rw-r--r-- | src/mir/mir_builder.cpp | 11 | ||||
-rw-r--r-- | src/trans/enumerate.cpp | 6 |
10 files changed, 105 insertions, 6 deletions
diff --git a/src/hir/deserialise.cpp b/src/hir/deserialise.cpp index de0d13da..d7dd74fe 100644 --- a/src/hir/deserialise.cpp +++ b/src/hir/deserialise.cpp @@ -963,6 +963,14 @@ namespace { m_in.read_bool() ? ::MIR::eDropKind::DEEP : ::MIR::eDropKind::SHALLOW, deserialise_mir_lvalue() }); + case 2: + return ::MIR::Statement::make_Asm({ + m_in.read_string(), + deserialise_vec< ::std::pair< ::std::string, ::MIR::LValue> >(), + deserialise_vec< ::std::pair< ::std::string, ::MIR::LValue> >(), + deserialise_vec< ::std::string>(), + deserialise_vec< ::std::string>() + }); default: ::std::cerr << "Bad tag for a MIR Statement" << ::std::endl; throw ""; diff --git a/src/hir/serialise.cpp b/src/hir/serialise.cpp index 0dfb9b01..4feece50 100644 --- a/src/hir/serialise.cpp +++ b/src/hir/serialise.cpp @@ -474,6 +474,14 @@ namespace { assert(e.kind == ::MIR::eDropKind::DEEP || e.kind == ::MIR::eDropKind::SHALLOW); m_out.write_bool(e.kind == ::MIR::eDropKind::DEEP); serialise(e.slot); + ), + (Asm, + m_out.write_tag(2); + m_out.write_string(e.tpl); + serialise_vec(e.inputs); + serialise_vec(e.outputs); + serialise_vec(e.clobbers); + serialise_vec(e.flags); ) ) } diff --git a/src/mir/check.cpp b/src/mir/check.cpp index 0c428c64..e867c822 100644 --- a/src/mir/check.cpp +++ b/src/mir/check.cpp @@ -260,15 +260,22 @@ void MIR_Validate(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path const auto& stmt = bb.statements[stmt_idx]; state.set_cur_stmt(block, stmt_idx); - if( stmt.is_Drop() ) + switch( stmt.tag() ) { + case ::MIR::Statement::TAGDEAD: + throw ""; + case ::MIR::Statement::TAG_Drop: // Invalidate the slot val_state.ensure_valid(state, stmt.as_Drop().slot); val_state.mark_validity( state, stmt.as_Drop().slot, false ); - } - else - { - assert( stmt.is_Assign() ); + break; + case ::MIR::Statement::TAG_Asm: + for(const auto& v : stmt.as_Asm().inputs) + val_state.ensure_valid(state, v.second); + for(const auto& v : stmt.as_Asm().outputs) + val_state.mark_validity( state, v.second, true ); + break; + case ::MIR::Statement::TAG_Assign: // Check source (and invalidate sources) TU_MATCH( ::MIR::RValue, (stmt.as_Assign().src), (se), (Use, @@ -323,6 +330,7 @@ void MIR_Validate(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path ) // Mark destination as valid val_state.mark_validity( state, stmt.as_Assign().dst, true ); + break; } } @@ -557,6 +565,9 @@ void MIR_Validate(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path ) ) } break; + case ::MIR::Statement::TAG_Asm: + // TODO: Ensure that values are all thin pointers or integers? + break; case ::MIR::Statement::TAG_Drop: // TODO: Anything need checking here? break; diff --git a/src/mir/cleanup.cpp b/src/mir/cleanup.cpp index 5744a033..27410462 100644 --- a/src/mir/cleanup.cpp +++ b/src/mir/cleanup.cpp @@ -817,6 +817,12 @@ void MIR_Cleanup(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path, (Drop, MIR_Cleanup_LValue(state, mutator, se.slot); ), + (Asm, + for(auto& v : se.inputs) + MIR_Cleanup_LValue(state, mutator, v.second); + for(auto& v : se.outputs) + MIR_Cleanup_LValue(state, mutator, v.second); + ), (Assign, MIR_Cleanup_LValue(state, mutator, se.dst); TU_MATCHA( (se.src), (re), diff --git a/src/mir/dump.cpp b/src/mir/dump.cpp index d143c2c9..e10856bf 100644 --- a/src/mir/dump.cpp +++ b/src/mir/dump.cpp @@ -163,6 +163,22 @@ namespace { DEBUG("- Assign " << e.dst << " = " << e.src); m_os << FMT_M(e.dst) << " = " << FMT_M(e.src) << ";\n"; ), + (Asm, + DEBUG("- Asm"); + m_os << "("; + for(const auto& v : e.outputs) + m_os << FMT_M(v.second) << ","; + m_os << ") = asm!"; + m_os << "("; + for(const auto& v : e.inputs) + m_os << FMT_M(v.second) << ","; + m_os << " : "; + for(const auto& v : e.clobbers) + m_os << "\"" << v << "\","; + m_os << ")"; + for(const auto& v : e.flags) + m_os << " \"" << v << "\""; + ), (Drop, DEBUG("- DROP " << e.slot); m_os << "drop(" << FMT_M(e.slot); diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp index 3cfc8cac..a6a5aa32 100644 --- a/src/mir/from_hir.cpp +++ b/src/mir/from_hir.cpp @@ -451,7 +451,22 @@ namespace { { TRACE_FUNCTION_F("_Asm"); - TODO(node.span(), "asm!"); + ::std::vector< ::std::pair< ::std::string, ::MIR::LValue> > inputs; + for(auto& v : node.m_inputs) { + this->visit_node_ptr(v.value); + auto lv = m_builder.get_result_in_lvalue(v.value->span(), v.value->m_res_type); + inputs.push_back( ::std::make_pair(v.spec, mv$(lv)) ); + } + + ::std::vector< ::std::pair< ::std::string, ::MIR::LValue> > outputs; + for(auto& v : node.m_outputs) { + this->visit_node_ptr(v.value); + auto lv = m_builder.get_result_unwrap_lvalue(v.value->span()); + outputs.push_back( ::std::make_pair(v.spec, mv$(lv)) ); + } + + m_builder.push_stmt_asm( node.span(), { node.m_template, mv$(outputs), mv$(inputs), node.m_clobbers, node.m_flags } ); + m_builder.set_result(node.span(), ::MIR::RValue::make_Tuple({})); } void visit(::HIR::ExprNode_Return& node) override { diff --git a/src/mir/from_hir.hpp b/src/mir/from_hir.hpp index 405d4ffd..dc11232e 100644 --- a/src/mir/from_hir.hpp +++ b/src/mir/from_hir.hpp @@ -174,6 +174,8 @@ public: void push_stmt_drop(const Span& sp, ::MIR::LValue val); // Push a shallow drop (for Box) void push_stmt_drop_shallow(const Span& sp, ::MIR::LValue val); + // Push an inline assembly statement (NOTE: inputs aren't marked as moved) + void push_stmt_asm(const Span& sp, ::MIR::Statement::Data_Asm data); // - Block management bool block_active() const { diff --git a/src/mir/mir.hpp b/src/mir/mir.hpp index 5a6b83de..6bd371b5 100644 --- a/src/mir/mir.hpp +++ b/src/mir/mir.hpp @@ -200,11 +200,27 @@ enum class eDropKind { DEEP, }; TAGGED_UNION(Statement, Assign, + // Value assigment (Assign, struct { LValue dst; RValue src; }), + // Inline assembly + (Asm, struct { + ::std::string tpl; + ::std::vector< ::std::pair<::std::string,LValue> > outputs; + ::std::vector< ::std::pair<::std::string,LValue> > inputs; + ::std::vector< ::std::string> clobbers; + ::std::vector< ::std::string> flags; + }), + // Update the state of a drop flag + //(SetDropFlag, struct { + // unsigned int idx; + // bool new_val; + // }), + // Drop a value (Drop, struct { + //unsigned int flag_idx; // Valid if != ~0u eDropKind kind; // NOTE: For the `box` primitive LValue slot; }) diff --git a/src/mir/mir_builder.cpp b/src/mir/mir_builder.cpp index 17cf79ec..6df64a0e 100644 --- a/src/mir/mir_builder.cpp +++ b/src/mir/mir_builder.cpp @@ -280,6 +280,17 @@ void MirBuilder::push_stmt_drop_shallow(const Span& sp, ::MIR::LValue val) DEBUG("DROP shallow " << val); m_output.blocks.at(m_current_block).statements.push_back( ::MIR::Statement::make_Drop({ ::MIR::eDropKind::SHALLOW, mv$(val) }) ); } +void MirBuilder::push_stmt_asm(const Span& sp, ::MIR::Statement::Data_Asm data) +{ + ASSERT_BUG(sp, m_block_active, "Pushing statement with no active block"); + + // 1. Mark outputs as valid + for(const auto& v : data.outputs) + mark_value_assigned(sp, v.second); + + // 2. Push + m_output.blocks.at(m_current_block).statements.push_back( ::MIR::Statement::make_Asm( mv$(data) ) ); +} void MirBuilder::mark_value_assigned(const Span& sp, const ::MIR::LValue& dst) { diff --git a/src/trans/enumerate.cpp b/src/trans/enumerate.cpp index 81b02199..7462a2d9 100644 --- a/src/trans/enumerate.cpp +++ b/src/trans/enumerate.cpp @@ -749,6 +749,12 @@ void Trans_Enumerate_FillFrom_MIR(TransList& out, const ::HIR::Crate& crate, con ) ) ), + (Asm, + for(const auto& v : se.inputs) + Trans_Enumerate_FillFrom_MIR_LValue(out,crate, v.second, pp); + for(const auto& v : se.outputs) + Trans_Enumerate_FillFrom_MIR_LValue(out,crate, v.second, pp); + ), (Drop, Trans_Enumerate_FillFrom_MIR_LValue(out,crate, se.slot, pp); // TODO: Ensure that the drop glue for this type is generated |