From ee38738e083079e4f8d529ac58781aae47e09188 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 20 Aug 2017 10:46:02 +0800 Subject: Codegen C - Rough support for msvc inline assembly --- src/trans/codegen_c.cpp | 216 ++++++++++++++++++++++++++++++------------------ 1 file changed, 137 insertions(+), 79 deletions(-) (limited to 'src') diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp index 973aa33a..23d02531 100644 --- a/src/trans/codegen_c.cpp +++ b/src/trans/codegen_c.cpp @@ -2036,82 +2036,17 @@ namespace { if( e.flag_idx != ~0u ) m_of << indent << "}\n"; break; } - case ::MIR::Statement::TAG_Asm: { - const auto& e = stmt.as_Asm(); - - struct H { - static bool has_flag(const ::std::vector<::std::string>& flags, const char* des) { - return ::std::find_if(flags.begin(), flags.end(), [des](const auto&x){return x==des;}) != flags.end(); - } - static const char* convert_reg(const char* r) { - if( ::std::strcmp(r, "{eax}") == 0 || ::std::strcmp(r, "{rax}") == 0 ) { - return "a"; - } - else { - return r; - } - } - }; - bool is_volatile = H::has_flag(e.flags, "volatile"); - bool is_intel = H::has_flag(e.flags, "intel"); - - m_of << indent << "__asm__ "; - if(is_volatile) m_of << "__volatile__"; - // TODO: Convert format string? - // TODO: Use a C-specific escaper here. - m_of << "(\"" << (is_intel ? ".syntax intel; " : ""); - for(auto it = e.tpl.begin(); it != e.tpl.end(); ++it) - { - if( *it == '\n' ) - m_of << ";\\n"; - else if( *it == '"' ) - m_of << "\\\""; - else if( *it == '\\' ) - m_of << "\\\\"; - else if( *it == '/' && *(it+1) == '/' ) - { - while( it != e.tpl.end() || *it == '\n' ) - ++it; - -- it; - } - else if( *it == '%' && *(it+1) == '%' ) - m_of << "%"; - else if( *it == '%' && !isdigit(*(it+1)) ) - m_of << "%%"; - else - m_of << *it; - } - m_of << (is_intel ? ".syntax att; " : "") << "\""; - m_of << ": "; - for(unsigned int i = 0; i < e.outputs.size(); i ++ ) - { - const auto& v = e.outputs[i]; - if( i != 0 ) m_of << ", "; - m_of << "\""; - switch(v.first[0]) - { - case '=': m_of << "="; break; - case '+': m_of << "+"; break; - default: MIR_TODO(mir_res, "Handle asm! output leader '" << v.first[0] << "'"); - } - m_of << H::convert_reg(v.first.c_str()+1); - m_of << "\"("; emit_lvalue(v.second); m_of << ")"; - } - m_of << ": "; - for(unsigned int i = 0; i < e.inputs.size(); i ++ ) - { - const auto& v = e.inputs[i]; - if( i != 0 ) m_of << ", "; - m_of << "\"" << v.first << "\"("; emit_lvalue(v.second); m_of << ")"; - } - m_of << ": "; - for(unsigned int i = 0; i < e.clobbers.size(); i ++ ) + case ::MIR::Statement::TAG_Asm: + switch(m_compiler) { - if( i != 0 ) m_of << ", "; - m_of << "\"" << e.clobbers[i] << "\""; + case Compiler::Gcc: + this->emit_asm_gcc(mir_res, stmt.as_Asm(), indent_level); + break; + case Compiler::Msvc: + this->emit_asm_msvc(mir_res, stmt.as_Asm(), indent_level); + break; } - m_of << ");\n"; - break; } + break; case ::MIR::Statement::TAG_Assign: { const auto& e = stmt.as_Assign(); DEBUG("- " << e.dst << " = " << e.src); @@ -2815,6 +2750,121 @@ namespace { } m_of << " );\n"; } + void emit_asm_gcc(const ::MIR::TypeResolve& mir_res, const ::MIR::Statement::Data_Asm& e, unsigned indent_level) + { + auto indent = RepeatLitStr{ "\t", static_cast(indent_level) }; + struct H { + static bool has_flag(const ::std::vector<::std::string>& flags, const char* des) { + return ::std::find_if(flags.begin(), flags.end(), [des](const auto&x) {return x == des; }) != flags.end(); + } + static const char* convert_reg(const char* r) { + if (::std::strcmp(r, "{eax}") == 0 || ::std::strcmp(r, "{rax}") == 0) { + return "a"; + } + else { + return r; + } + } + }; + bool is_volatile = H::has_flag(e.flags, "volatile"); + bool is_intel = H::has_flag(e.flags, "intel"); + + + m_of << indent << "__asm__ "; + if (is_volatile) m_of << "__volatile__"; + // TODO: Convert format string? + // TODO: Use a C-specific escaper here. + m_of << "(\"" << (is_intel ? ".syntax intel; " : ""); + for (auto it = e.tpl.begin(); it != e.tpl.end(); ++it) + { + if (*it == '\n') + m_of << ";\\n"; + else if (*it == '"') + m_of << "\\\""; + else if (*it == '\\') + m_of << "\\\\"; + else if (*it == '/' && *(it + 1) == '/') + { + while (it != e.tpl.end() || *it == '\n') + ++it; + --it; + } + else if (*it == '%' && *(it + 1) == '%') + m_of << "%"; + else if (*it == '%' && !isdigit(*(it + 1))) + m_of << "%%"; + else + m_of << *it; + } + m_of << (is_intel ? ".syntax att; " : "") << "\""; + m_of << ": "; + for (unsigned int i = 0; i < e.outputs.size(); i++) + { + const auto& v = e.outputs[i]; + if (i != 0) m_of << ", "; + m_of << "\""; + switch (v.first[0]) + { + case '=': m_of << "="; break; + case '+': m_of << "+"; break; + default: MIR_TODO(mir_res, "Handle asm! output leader '" << v.first[0] << "'"); + } + m_of << H::convert_reg(v.first.c_str() + 1); + m_of << "\"("; emit_lvalue(v.second); m_of << ")"; + } + m_of << ": "; + for (unsigned int i = 0; i < e.inputs.size(); i++) + { + const auto& v = e.inputs[i]; + if (i != 0) m_of << ", "; + m_of << "\"" << v.first << "\"("; emit_lvalue(v.second); m_of << ")"; + } + m_of << ": "; + for (unsigned int i = 0; i < e.clobbers.size(); i++) + { + if (i != 0) m_of << ", "; + m_of << "\"" << e.clobbers[i] << "\""; + } + m_of << ");\n"; + } + void emit_asm_msvc(const ::MIR::TypeResolve& mir_res, const ::MIR::Statement::Data_Asm& e, unsigned indent_level) + { + auto indent = RepeatLitStr{ "\t", static_cast(indent_level) }; + + if( !e.inputs.empty() || !e.outputs.empty() ) + { + MIR_TODO(mir_res, "Inputs/outputs in msvc inline assembly"); +#if 0 + m_of << indent << "{\n"; + for(size_t i = 0; i < e.inputs.size(); i ++) + { + m_of << indent << "auto asm_i_" << i << " = "; + emit_lvalue(e.inputs[i]); + } +#endif + } + + m_of << indent << "__asm {\n"; + + m_of << indent << "\t"; + for (auto it = e.tpl.begin(); it != e.tpl.end(); ++it) + { + if (*it == ';') + { + m_of << "\n"; + m_of << indent << "\t"; + } + else + m_of << *it; + } + + m_of << "\n" << indent << "}"; + if (!e.inputs.empty() || !e.outputs.empty()) + { + m_of << "}"; + } + m_of << ";\n"; + } private: const ::HIR::TypeRef& monomorphise_fcn_return(::HIR::TypeRef& tmp, const ::HIR::Function& item, const Trans_Params& params) { @@ -4154,13 +4204,21 @@ namespace { m_of << "\", " << ::std::dec << c.size() << ")"; ), (Const, - // TODO: This should have been eliminated? - // NOTE: GCC hack - statement expressions + // TODO: This should have been eliminated? ("MIR Cleanup" should have removed all inline Const references) ::HIR::TypeRef ty; const auto& lit = get_literal_for_const(c.p, ty); - m_of << "({"; emit_ctype(ty, FMT_CB(ss, ss<<"v";)); m_of << "; "; - assign_from_literal([&](){ m_of << "v"; }, ty, lit); - m_of << "; v;})"; + if(lit.is_Integer() || lit.is_Float() || lit.is_String()) + { + emit_literal(ty, lit, {}); + } + else + { + // NOTE: GCC hack - statement expressions + MIR_ASSERT(*m_mir_res, m_compiler == Compiler::Gcc, "TODO: Support inline constants without statement expressions"); + m_of << "({"; emit_ctype(ty, FMT_CB(ss, ss<<"v";)); m_of << "; "; + assign_from_literal([&](){ m_of << "v"; }, ty, lit); + m_of << "; v;})"; + } ), (ItemAddr, TU_MATCHA( (c.m_data), (pe), -- cgit v1.2.3 From aa44379d158085d649d9ab3514e0c2276d2d5076 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 20 Aug 2017 20:56:00 +0800 Subject: Load Crates - Search passed library directories for crates --- src/ast/crate.cpp | 23 +++++++++++++++++------ src/ast/crate.hpp | 3 +++ src/main.cpp | 11 +++++++++++ 3 files changed, 31 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/ast/crate.cpp b/src/ast/crate.cpp index 394cd47b..f003a00b 100644 --- a/src/ast/crate.cpp +++ b/src/ast/crate.cpp @@ -8,6 +8,9 @@ #include // HIR_Deserialise #include +::std::vector<::std::string> AST::g_crate_load_dirs = { }; +::std::map<::std::string, ::std::string> AST::g_crate_overrides; + namespace { bool check_item_cfg(const ::AST::MetaItems& attrs) { @@ -99,15 +102,23 @@ void Crate::load_externs() void Crate::load_extern_crate(Span sp, const ::std::string& name) { DEBUG("Loading crate '" << name << "'"); - // TODO: Search a list of load paths for the crate - ::std::vector< ::std::string> paths { "output/", "output/test_deps/" }; ::std::string path; - for(const auto& p : paths){ - path = p + "lib" + name + ".hir"; + auto it = g_crate_overrides.find(name); + if(it != g_crate_overrides.end()) + { + path = it->second; + } + else + { + // Search a list of load paths for the crate + for(const auto& p : g_crate_load_dirs) + { + path = p + "/lib" + name + ".hir"; - if( ::std::ifstream(path).good() ) { - break ; + if( ::std::ifstream(path).good() ) { + break ; + } } } if( !::std::ifstream(path).good() ) { diff --git a/src/ast/crate.hpp b/src/ast/crate.hpp index f9594a83..53dea1b9 100644 --- a/src/ast/crate.hpp +++ b/src/ast/crate.hpp @@ -89,4 +89,7 @@ public: const MacroRules* find_macro_rules(const ::std::string& name) const; }; +extern ::std::vector<::std::string> g_crate_load_dirs; +extern ::std::map<::std::string, ::std::string> g_crate_overrides; + } // namespace AST diff --git a/src/main.cpp b/src/main.cpp index 7b1d94be..b883a828 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -224,6 +224,11 @@ int main(int argc, char *argv[]) // Load external crates. CompilePhaseV("LoadCrates", [&]() { + // Hacky! + for(const auto& ld : params.lib_search_dirs) + { + AST::g_crate_load_dirs.push_back(ld); + } crate.load_externs(); }); @@ -570,6 +575,12 @@ int main(int argc, char *argv[]) // ::std::cerr << "Internal Compiler Error: " << e << ::std::endl; // return 2; //} + + // TODO: Make this conditional +#if 0 + ::std::cout << "Press enter to exit..." << ::std::endl; + ::std::cin.get(); +#endif return 0; } -- cgit v1.2.3 From 3d2faba77cdb2695753a4c62641b7f92a573869b Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 20 Aug 2017 20:56:24 +0800 Subject: Misc - Visual studio cleanups --- .gitignore | 1 + src/expand/format_args.cpp | 2 +- vsproject/mrustc.sln | 3 + vsproject/mrustc.vcxproj.filters | 180 +++++++++++++++++++++------------------ 4 files changed, 101 insertions(+), 85 deletions(-) (limited to 'src') diff --git a/.gitignore b/.gitignore index 4488f48c..b1d89c5d 100644 --- a/.gitignore +++ b/.gitignore @@ -45,3 +45,4 @@ /bnf/rust.tab.h /bnf/rust.output /bnf/test.bin +/vsproject/output diff --git a/src/expand/format_args.cpp b/src/expand/format_args.cpp index 92afcbb2..e4c02b8b 100644 --- a/src/expand/format_args.cpp +++ b/src/expand/format_args.cpp @@ -477,7 +477,7 @@ class CFormatArgsExpander: auto expr_tt = TokenTree(Token( InterpolatedFragment(InterpolatedFragment::EXPR, Parse_Expr0(lex).release()) )); - auto ins_rv = named_args_index.insert( ::std::make_pair(mv$(name), named_args.size()) ); + auto ins_rv = named_args_index.insert( ::std::make_pair(mv$(name), static_cast(named_args.size())) ); if( ins_rv.second == false ) { ERROR(sp, E0000, "Duplicate definition of named argument `" << ins_rv.first->first << "`"); } diff --git a/vsproject/mrustc.sln b/vsproject/mrustc.sln index 3aebce2e..abeaf785 100644 --- a/vsproject/mrustc.sln +++ b/vsproject/mrustc.sln @@ -8,6 +8,9 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tu_test", "tu_test\tu_test.vcxproj", "{F0A80ABB-A11A-492C-B5FC-E26C29A988D8}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "minicargo", "minicargo\minicargo.vcxproj", "{15F3D38B-14FF-4872-805D-6D9C52920842}" + ProjectSection(ProjectDependencies) = postProject + {12AA9964-C1BD-406A-9545-43EE63230EBE} = {12AA9964-C1BD-406A-9545-43EE63230EBE} + EndProjectSection EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/vsproject/mrustc.vcxproj.filters b/vsproject/mrustc.vcxproj.filters index e5afb22e..cfcdb9b9 100644 --- a/vsproject/mrustc.vcxproj.filters +++ b/vsproject/mrustc.vcxproj.filters @@ -57,6 +57,18 @@ {1233e2f6-7b44-4379-9f43-d572b8944ba0} + + {3709226c-e95b-4da0-9735-42e2a5cad1a7} + + + {c78c419b-2b25-4c6f-8f91-95a9d0142fff} + + + {6bbfdfb3-9557-43a9-bddd-07a243569fa3} + + + {e3219c19-8898-418e-b2ba-84254977a792} + @@ -382,63 +394,21 @@ Header Files - - Header Files - - - Header Files - - - Header Files - Header Files - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - Header Files - - Header Files - - - Header Files - - - Header Files - Header Files Header Files - - Header Files - Header Files - - Header Files - Header Files @@ -457,12 +427,6 @@ Header Files - - Header Files - - - Header Files - Header Files @@ -487,57 +451,21 @@ Header Files - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - Header Files Header Files - - Header Files - - - Header Files - Header Files - - Header Files - - - Header Files - - - Header Files - Header Files Header Files - - Header Files - - - Header Files - Header Files\ast @@ -583,6 +511,90 @@ Header Files\ast + + Header Files\ast + + + Header Files\parse + + + Header Files\hir + + + Header Files\parse + + + Header Files\hir + + + Header Files\hir_typeck + + + Header Files\hir + + + Header Files\mir + + + Header Files\hir + + + Header Files\hir + + + Header Files\expand + + + Header Files\trans + + + Header Files\hir + + + Header Files\mir + + + Header Files\mir + + + Header Files\hir + + + Header Files\parse + + + Header Files\hir + + + Header Files\ast + + + Header Files\hir_typeck + + + Header Files\hir + + + Header Files\hir + + + Header Files\mir + + + Header Files\parse + + + Header Files\parse + + + Header Files\trans + + + Header Files\parse + + + Header Files\parse + -- cgit v1.2.3 From a463c0ec69b7cdefc26277ec5f3b36def7b7f70e Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 20 Aug 2017 21:00:14 +0800 Subject: Codegen C - Fix a few bugs with MSVC mode --- src/trans/codegen_c.cpp | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp index 23d02531..b7c3806a 100644 --- a/src/trans/codegen_c.cpp +++ b/src/trans/codegen_c.cpp @@ -499,7 +499,9 @@ namespace { break; case Compiler::Msvc: is_windows = true; + // TODO: Look up these paths in the registry and use CreateProcess instead of system args.push_back(cache_str( detect_msvc().path_vcvarsall )); + //args.push_back("amd64"); args.push_back("&"); args.push_back("cl.exe"); args.push_back("/nologo"); @@ -568,8 +570,9 @@ namespace { } //DEBUG("- " << cmd_ss.str()); ::std::cout << "Running comamnd - " << cmd_ss.str() << ::std::endl; - if( system(cmd_ss.str().c_str()) ) + if( system(cmd_ss.str().c_str()) != 0 ) { + ::std::cerr << "C Compiler failed to execute" << ::std::endl; abort(); } } @@ -3010,6 +3013,7 @@ namespace { m_of << ", "< Date: Sun, 20 Aug 2017 21:00:31 +0800 Subject: HIR From AST - i128/u128 --- src/hir/from_ast_expr.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/hir/from_ast_expr.cpp b/src/hir/from_ast_expr.cpp index 9bbb0418..545873ed 100644 --- a/src/hir/from_ast_expr.cpp +++ b/src/hir/from_ast_expr.cpp @@ -441,6 +441,8 @@ struct LowerHIR_ExprNode_Visitor: case CORETYPE_U32: return ::HIR::CoreType::U32; case CORETYPE_I64: return ::HIR::CoreType::I64; case CORETYPE_U64: return ::HIR::CoreType::U64; + case CORETYPE_I128: return ::HIR::CoreType::I128; + case CORETYPE_U128: return ::HIR::CoreType::U128; case CORETYPE_INT: return ::HIR::CoreType::Isize; case CORETYPE_UINT: return ::HIR::CoreType::Usize; -- cgit v1.2.3