diff options
author | John Hodge <tpg@mutabah.net> | 2019-10-26 17:15:23 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2019-10-26 17:15:23 +0800 |
commit | 99904636d2e1e335238552cbb5b8b23dd06b7295 (patch) | |
tree | 5fd6470fb702b2a26253d380d47d5b6fd232607f /src | |
parent | 7ca04e2d668fa44a1663158f844cb912e396cb32 (diff) | |
parent | ebd8edeb4f1861943cc82d310564b1f592e63272 (diff) | |
download | mrust-99904636d2e1e335238552cbb5b8b23dd06b7295.tar.gz |
Merge remote-tracking branch 'remotes/origin/master' into nightly-1.29
Diffstat (limited to 'src')
-rw-r--r-- | src/ast/expr.hpp | 1 | ||||
-rw-r--r-- | src/expand/derive.cpp | 1 | ||||
-rw-r--r-- | src/expand/proc_macro.cpp | 2 | ||||
-rw-r--r-- | src/hir/expr.hpp | 1 | ||||
-rw-r--r-- | src/hir/expr_ptr.hpp | 2 | ||||
-rw-r--r-- | src/hir_typeck/expr_cs.cpp | 8 | ||||
-rw-r--r-- | src/hir_typeck/helpers.cpp | 4 | ||||
-rw-r--r-- | src/include/span.hpp | 10 | ||||
-rw-r--r-- | src/include/synext_decorator.hpp | 1 | ||||
-rw-r--r-- | src/macro_rules/macro_rules_ptr.hpp | 2 | ||||
-rw-r--r-- | src/macro_rules/mod.cpp | 6 | ||||
-rw-r--r-- | src/macro_rules/parse.cpp | 1 | ||||
-rw-r--r-- | src/main.cpp | 32 | ||||
-rw-r--r-- | src/mir/cleanup.cpp | 2 | ||||
-rw-r--r-- | src/parse/token.cpp | 1 | ||||
-rw-r--r-- | src/parse/tokenstream.cpp | 2 | ||||
-rw-r--r-- | src/rc_string.cpp | 4 | ||||
-rw-r--r-- | src/span.cpp | 9 | ||||
-rw-r--r-- | src/trans/codegen_c.cpp | 45 | ||||
-rw-r--r-- | src/trans/codegen_mmir.cpp | 20 | ||||
-rw-r--r-- | src/trans/target.cpp | 163 | ||||
-rw-r--r-- | src/trans/target.hpp | 42 |
22 files changed, 253 insertions, 106 deletions
diff --git a/src/ast/expr.hpp b/src/ast/expr.hpp index a9c82efa..6cfda001 100644 --- a/src/ast/expr.hpp +++ b/src/ast/expr.hpp @@ -636,6 +636,7 @@ struct ExprNode_UniOp: class NodeVisitor { public: + virtual ~NodeVisitor() = default; inline void visit(const unique_ptr<ExprNode>& cnode) { if(cnode.get()) cnode->visit(*this); diff --git a/src/expand/derive.cpp b/src/expand/derive.cpp index 0ccda406..a14a12a3 100644 --- a/src/expand/derive.cpp +++ b/src/expand/derive.cpp @@ -156,6 +156,7 @@ struct DeriveOpts /// Interface for derive handlers struct Deriver { + virtual ~Deriver() = default; virtual const char* trait_name() const = 0; virtual AST::Impl handle_item(Span sp, const DeriveOpts& opts, const AST::GenericParams& p, const TypeRef& type, const AST::Struct& str) const = 0; virtual AST::Impl handle_item(Span sp, const DeriveOpts& opts, const AST::GenericParams& p, const TypeRef& type, const AST::Enum& enm) const = 0; diff --git a/src/expand/proc_macro.cpp b/src/expand/proc_macro.cpp index 3b23184e..bc882d77 100644 --- a/src/expand/proc_macro.cpp +++ b/src/expand/proc_macro.cpp @@ -1008,7 +1008,7 @@ uint64_t ProcMacroInv::recv_v128u() for(;;) { auto b = recv_u8(); - v |= static_cast<uint64_t>(b) << ofs; + v |= static_cast<uint64_t>(b & 0x7F) << ofs; if( (b & 0x80) == 0 ) break; ofs += 7; diff --git a/src/hir/expr.hpp b/src/hir/expr.hpp index 2ca960e3..c87ae3a7 100644 --- a/src/hir/expr.hpp +++ b/src/hir/expr.hpp @@ -821,6 +821,7 @@ struct ExprNode_Closure: class ExprVisitor { public: + virtual ~ExprVisitor() = default; virtual void visit_node_ptr(::std::unique_ptr<ExprNode>& node_ptr); virtual void visit_node(ExprNode& node); #define NV(nt) virtual void visit(nt& n) = 0; diff --git a/src/hir/expr_ptr.hpp b/src/hir/expr_ptr.hpp index 58fa3762..512921eb 100644 --- a/src/hir/expr_ptr.hpp +++ b/src/hir/expr_ptr.hpp @@ -12,7 +12,7 @@ #include <mir/mir_ptr.hpp> -class Span; +struct Span; namespace HIR { diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp index 10cb9407..8a374946 100644 --- a/src/hir_typeck/expr_cs.cpp +++ b/src/hir_typeck/expr_cs.cpp @@ -46,6 +46,7 @@ struct Context class Revisitor { public: + virtual ~Revisitor() = default; virtual const Span& span() const = 0; virtual void fmt(::std::ostream& os) const = 0; virtual bool revisit(Context& context, bool is_fallback) = 0; @@ -6667,13 +6668,8 @@ namespace { if( H::type_is_num(left) && H::type_is_num(right) ) { DEBUG("- Magic inferrence link for binops on numerics"); context.equate_types(sp, res, left); - const auto& right = context.get_type(v.params.m_types.at(0)); - context.equate_types_to_shadow(sp, right); - } - else - { - context.equate_types_to_shadow(sp, right); } + context.equate_types_to_shadow(sp, /*right*/v.params.m_types.at(0)); // RHS, can't use `right` because it might be freed by the above equate. } else { diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp index 08e817de..010df546 100644 --- a/src/hir_typeck/helpers.cpp +++ b/src/hir_typeck/helpers.cpp @@ -636,7 +636,7 @@ void HMTypeInferrence::set_ivar_to(unsigned int slot, ::HIR::TypeRef type) } else #endif - root_ivar.type = box$( mv$(type) ); + root_ivar.type = box$( type ); } this->mark_change(); @@ -1648,7 +1648,7 @@ bool TraitResolution::has_associated_type(const ::HIR::TypeRef& input) const //TRACE_FUNCTION_F(input); TU_MATCH(::HIR::TypeRef::Data, (input.m_data), (e), (Infer, - auto& ty = this->m_ivars.get_type(input); + const auto& ty = this->m_ivars.get_type(input); if( ty != input ) { return this->has_associated_type(ty); } diff --git a/src/include/span.hpp b/src/include/span.hpp index 51c3440c..970a2ad0 100644 --- a/src/include/span.hpp +++ b/src/include/span.hpp @@ -29,9 +29,9 @@ struct ProtoSpan unsigned int start_line; unsigned int start_ofs; }; -class Span +struct Span { -public: +//public: ::std::shared_ptr<Span> outer_span; // Expansion target for macros RcString filename; @@ -47,10 +47,14 @@ public: end_line(end_line), end_ofs(end_ofs) {} - Span(const Span& x); + Span(const Span& x) = default; + Span(Span&& x) = default; Span(const Position& position); Span(); + Span& operator=(const Span& x) = default; + Span& operator=(Span&& x) = default; + void bug(::std::function<void(::std::ostream&)> msg) const; void error(ErrorType tag, ::std::function<void(::std::ostream&)> msg) const; void warning(WarningType tag, ::std::function<void(::std::ostream&)> msg) const; diff --git a/src/include/synext_decorator.hpp b/src/include/synext_decorator.hpp index c910f6c0..88a6258c 100644 --- a/src/include/synext_decorator.hpp +++ b/src/include/synext_decorator.hpp @@ -46,6 +46,7 @@ class ExpandDecorator { void unexpected(const Span& sp, const AST::Attribute& mi, const char* loc_str) const; public: + virtual ~ExpandDecorator() = default; virtual AttrStage stage() const = 0; virtual void handle(const Span& sp, const AST::Attribute& mi, AST::Crate& crate) const { unexpected(sp, mi, "crate"); } diff --git a/src/macro_rules/macro_rules_ptr.hpp b/src/macro_rules/macro_rules_ptr.hpp index fdb01fbe..5dbfd032 100644 --- a/src/macro_rules/macro_rules_ptr.hpp +++ b/src/macro_rules/macro_rules_ptr.hpp @@ -14,7 +14,7 @@ class MacroRulesPtr MacroRules* m_ptr; public: MacroRulesPtr(): m_ptr(nullptr) {} - MacroRulesPtr(MacroRules* p): m_ptr(p) {} + MacroRulesPtr(MacroRules* p); MacroRulesPtr(MacroRulesPtr&& x): m_ptr(x.m_ptr) { diff --git a/src/macro_rules/mod.cpp b/src/macro_rules/mod.cpp index e9ecb504..2ad325b8 100644 --- a/src/macro_rules/mod.cpp +++ b/src/macro_rules/mod.cpp @@ -168,10 +168,16 @@ bool is_token_vis(eTokenType tt) { } } +MacroRulesPtr::MacroRulesPtr(MacroRules* p): + m_ptr(p) +{ + //::std::cout << "MRP new " << m_ptr << ::std::endl; +} MacroRulesPtr::~MacroRulesPtr() { if(m_ptr) { + //::std::cout << "MRP delete " << m_ptr << ::std::endl; delete m_ptr; m_ptr = nullptr; } diff --git a/src/macro_rules/parse.cpp b/src/macro_rules/parse.cpp index 43ffb097..6a476ef1 100644 --- a/src/macro_rules/parse.cpp +++ b/src/macro_rules/parse.cpp @@ -265,6 +265,7 @@ MacroRule Parse_MacroRules_Var(TokenStream& lex) { case TOK_BRACE_OPEN: close = TOK_BRACE_CLOSE; break; case TOK_PAREN_OPEN: close = TOK_PAREN_CLOSE; break; + case TOK_SQUARE_OPEN: close = TOK_SQUARE_CLOSE; break; default: throw ParseError::Unexpected(lex, tok); } diff --git a/src/main.cpp b/src/main.cpp index 0efddc5f..c722bc73 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -38,6 +38,7 @@ TargetVersion gTargetVersion = TargetVersion::Rustc1_29; void init_debug_list() { + g_debug_disable_map.insert( "Target Load" ); g_debug_disable_map.insert( "Parse" ); g_debug_disable_map.insert( "LoadCrates" ); g_debug_disable_map.insert( "Expand" ); @@ -159,6 +160,9 @@ struct ProgramParams bool test_harness = false; + // NOTE: If populated, nothing happens except for loading the target + ::std::string target_saveback; + ::std::vector<const char*> lib_search_dirs; ::std::vector<const char*> libraries; ::std::map<::std::string, ::std::string> crate_overrides; // --extern name=path @@ -217,8 +221,21 @@ int main(int argc, char *argv[]) Cfg_SetValueCb("feature", [¶ms](const ::std::string& s) { return params.features.count(s) != 0; }); - Target_SetCfg(params.target); + CompilePhaseV("Target Load", [&]() { + Target_SetCfg(params.target); + }); + if( params.target_saveback != "") + { + Target_ExportCurSpec(params.target_saveback); + return 0; + } + + if( params.infile == "" ) + { + ::std::cerr << "No input file passed" << ::std::endl; + return 1; + } if( params.test_harness ) { @@ -1100,6 +1117,13 @@ ProgramParams::ProgramParams(int argc, char *argv[]) } this->target = argv[++i]; } + else if( strcmp(arg, "--dump-target-spec") == 0 ) { + if (i == argc - 1) { + ::std::cerr << "Flag " << arg << " requires an argument" << ::std::endl; + exit(1); + } + this->target_saveback = argv[++i]; + } else if( strcmp(arg, "--test") == 0 ) { this->test_harness = true; } @@ -1110,12 +1134,6 @@ ProgramParams::ProgramParams(int argc, char *argv[]) } } - if (this->infile == "") - { - ::std::cerr << "No input file passed" << ::std::endl; - exit(1); - } - if( const auto* a = getenv("MRUSTC_TARGET_VER") ) { diff --git a/src/mir/cleanup.cpp b/src/mir/cleanup.cpp index ef2a24aa..6b8bcf79 100644 --- a/src/mir/cleanup.cpp +++ b/src/mir/cleanup.cpp @@ -1264,7 +1264,7 @@ void MIR_Cleanup(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path, void MIR_CleanupCrate(::HIR::Crate& crate) { - ::MIR::OuterVisitor ov { crate, [&](const auto& res, const auto& p, auto& expr_ptr, const auto& args, const auto& ty){ + ::MIR::OuterVisitor ov { crate, [&](const auto& res, const auto& p, ::HIR::ExprPtr& expr_ptr, const auto& args, const auto& ty){ MIR_Cleanup(res, p, expr_ptr.get_mir_or_error_mut(Span()), args, ty); } }; ov.visit_crate(crate); diff --git a/src/parse/token.cpp b/src/parse/token.cpp index 900108ab..f9ecd028 100644 --- a/src/parse/token.cpp +++ b/src/parse/token.cpp @@ -229,6 +229,7 @@ Token Token::clone() const BUG(m_pos, "Fragment with invalid token type (" << *this << ")"); break; } + assert(rv.m_data.is_Fragment()); ) ) return rv; diff --git a/src/parse/tokenstream.cpp b/src/parse/tokenstream.cpp index 957bc673..6f0c57a1 100644 --- a/src/parse/tokenstream.cpp +++ b/src/parse/tokenstream.cpp @@ -125,7 +125,7 @@ ProtoSpan TokenStream::start_span() const Span TokenStream::end_span(ProtoSpan ps) const { auto p = this->getPosition(); - auto rv = Span( ps.filename, ps.start_line, ps.start_ofs, p.line, p.ofs ); + auto rv = Span( ::std::move(ps.filename), ps.start_line, ps.start_ofs, p.line, p.ofs ); rv.outer_span = this->outerSpan(); return rv; } diff --git a/src/rc_string.cpp b/src/rc_string.cpp index 260ba90a..b56f2e62 100644 --- a/src/rc_string.cpp +++ b/src/rc_string.cpp @@ -23,6 +23,8 @@ RcString::RcString(const char* s, unsigned int len): for(unsigned int j = 0; j < len; j ++ ) data_mut[j] = s[j]; data_mut[len] = '\0'; + + //::std::cout << "RcString(" << m_ptr << " \"" << *this << "\") - " << *m_ptr << " (creation)" << ::std::endl; } } RcString::~RcString() @@ -30,7 +32,7 @@ RcString::~RcString() if(m_ptr) { *m_ptr -= 1; - //::std::cout << "RcString(\"" << *this << "\") - " << *m_ptr << " refs left" << ::std::endl; + //::std::cout << "RcString(" << m_ptr << " \"" << *this << "\") - " << *m_ptr << " refs left (drop)" << ::std::endl; if( *m_ptr == 0 ) { delete[] m_ptr; diff --git a/src/span.cpp b/src/span.cpp index 035258d6..7e3968d1 100644 --- a/src/span.cpp +++ b/src/span.cpp @@ -11,15 +11,6 @@ #include <parse/lex.hpp> #include <common.hpp> -Span::Span(const Span& x): - outer_span(x.outer_span), - filename(x.filename), - start_line(x.start_line), - start_ofs(x.start_ofs), - end_line(x.end_line), - end_ofs(x.end_ofs) -{ -} Span::Span(const Position& pos): outer_span(), filename(pos.filename), diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp index 8ecf988a..8a392f86 100644 --- a/src/trans/codegen_c.cpp +++ b/src/trans/codegen_c.cpp @@ -200,20 +200,23 @@ namespace { m_outfile_path_c(outfile + ".c"), m_of(m_outfile_path_c) { + m_options.emulated_i128 = Target_GetCurSpec().m_backend_c.m_emulated_i128; switch(Target_GetCurSpec().m_backend_c.m_codegen_mode) { case CodegenMode::Gnu11: m_compiler = Compiler::Gcc; - m_options.emulated_i128 = false; - if( Target_GetCurSpec().m_arch.m_pointer_bits < 64 ) + if( Target_GetCurSpec().m_arch.m_pointer_bits < 64 && !m_options.emulated_i128 ) { - m_options.emulated_i128 = true; + WARNING(Span(), W0000, "Potentially misconfigured target, 32-bit targets require i128 emulation"); } m_options.disallow_empty_structs = true; break; case CodegenMode::Msvc: m_compiler = Compiler::Msvc; - m_options.emulated_i128 = true; + if( !m_options.emulated_i128 ) + { + WARNING(Span(), W0000, "Potentially misconfigured target, MSVC requires i128 emulation"); + } m_options.disallow_empty_structs = true; break; } @@ -297,7 +300,7 @@ namespace { // 64-bit bit ops (gcc intrinsics) m_of << "static inline uint64_t __builtin_clz64(uint64_t v) {\n" - << "\treturn (v >> 32 != 0 ? __builtin_clz(v>>32) : 32 + __builtin_clz(v));\n" + << "\treturn ( (v >> 32) != 0 ? __builtin_clz(v>>32) : 32 + __builtin_clz(v));\n" << "}\n" << "static inline uint64_t __builtin_ctz64(uint64_t v) {\n" << "\treturn ((v&0xFFFFFFFF) == 0 ? __builtin_ctz(v>>32) + 32 : __builtin_ctz(v));\n" @@ -322,10 +325,10 @@ namespace { << "static inline uint64_t __builtin_popcount(uint64_t v) {\n" << "\treturn (v >> 32 != 0 ? __popcnt64(v>>32) : 32 + __popcnt64(v));\n" << "}\n" - << "static inline int __builtin_ctz(uint32_t v) { int rv; _BitScanReverse(&rv, v); return rv; }\n" - << "static inline int __builtin_clz(uint32_t v) { int rv; _BitScanForward(&rv, v); return rv; }\n" + << "static inline int __builtin_ctz(uint32_t v) { int rv; _BitScanForward(&rv, v); return rv; }\n" + << "static inline int __builtin_clz(uint32_t v) { int rv; _BitScanReverse(&rv, v); return 31 - rv; }\n" << "static inline uint64_t __builtin_clz64(uint64_t v) {\n" - << "\treturn (v >> 32 != 0 ? __builtin_clz(v>>32) : 32 + __builtin_clz(v));\n" + << "\treturn ( (v >> 32) != 0 ? __builtin_clz(v>>32) : 32 + __builtin_clz(v) );\n" << "}\n" << "static inline uint64_t __builtin_ctz64(uint64_t v) {\n" << "\treturn ((v&0xFFFFFFFF) == 0 ? __builtin_ctz(v>>32) + 32 : __builtin_ctz(v));\n" @@ -776,13 +779,14 @@ namespace { if( getenv(varname.c_str()) ) { args.push_back( getenv(varname.c_str()) ); } + else if (system(("which " + Target_GetCurSpec().m_backend_c.m_c_compiler + "-gcc" + " >/dev/null 2>&1").c_str()) == 0) { + args.push_back( Target_GetCurSpec().m_backend_c.m_c_compiler + "-gcc" ); + } else if( getenv("CC") ) { args.push_back( getenv("CC") ); } else { - // TODO: Determine if the compiler can't be found, and fall back to `gcc` if that's the case - args.push_back( Target_GetCurSpec().m_backend_c.m_c_compiler + "-gcc" ); - //args.push_back( "gcc" ); + args.push_back("gcc"); } } for( const auto& a : Target_GetCurSpec().m_backend_c.m_compiler_opts ) @@ -1561,7 +1565,7 @@ namespace { assert(1 + union_fields.size() + 1 >= repr->fields.size()); // Make the union! // NOTE: The way the structure generation works is that enum variants are always first, so the field index = the variant index - // TODO: + // TODO: if( !this->type_is_bad_zst(repr->fields[0].ty) || ::std::any_of(union_fields.begin(), union_fields.end(), [this,repr](auto x){ return !this->type_is_bad_zst(repr->fields[x].ty); }) ) { m_of << "\tunion {\n"; @@ -2176,7 +2180,11 @@ namespace { (String, m_of << "{ "; this->print_escaped_string(e); - m_of << ", " << e.size() << "}"; + // TODO: Better type checking? + if( !ty.m_data.is_Array() ) { + m_of << ", " << e.size(); + } + m_of << "}"; ) ) } @@ -2219,9 +2227,8 @@ namespace { m_of << "\\x0" << (unsigned int)static_cast<uint8_t>(v); else m_of << "\\x" << (unsigned int)static_cast<uint8_t>(v); - // If the next character is a hex digit, - // close/reopen the string. - if( isxdigit(*(&v+1)) ) + // If the next character is a hex digit, close/reopen the string. + if( &v < &s.back() && isxdigit(*(&v+1)) ) m_of << "\"\""; } } @@ -3927,7 +3934,7 @@ namespace { m_of << "("; for(unsigned int j = 0; j < e.args.size(); j ++) { if(j != 0) m_of << ","; - m_of << " "; + m_of << " "; if( m_options.disallow_empty_structs && TU_TEST1(e.args[j], LValue, .is_Field()) ) { ::HIR::TypeRef tmp; @@ -4176,7 +4183,7 @@ namespace { void emit_intrinsic_call(const RcString& name, const ::HIR::PathParams& params, const ::MIR::Terminator::Data_Call& e) { const auto& mir_res = *m_mir_res; - enum class Ordering + enum class Ordering { SeqCst, Acquire, @@ -4341,7 +4348,7 @@ namespace { m_of << "*(volatile uint8_t*)"; else m_of << "*(volatile int8_t*)"; - emit_param(e.args.at(0)); + emit_param(e.args.at(0)); switch(op) { case AtomicOp::Add: m_of << " += "; break; diff --git a/src/trans/codegen_mmir.cpp b/src/trans/codegen_mmir.cpp index 97ac00eb..58739805 100644 --- a/src/trans/codegen_mmir.cpp +++ b/src/trans/codegen_mmir.cpp @@ -20,6 +20,14 @@ namespace { size_t PTR_BASE = 0x1000; // See matching value in standalone_miri value.hpp + size_t Target_GetSizeOf_Required(const Span& sp, const StaticTraitResolve& resolve, const ::HIR::TypeRef& ty) + { + size_t size; + bool type_has_size = Target_GetSizeOf(sp, resolve, ty, size); + ASSERT_BUG(sp, type_has_size, "Attempting to get the size of a unsized type"); + return size; + } + template<typename T> struct Fmt { @@ -874,8 +882,7 @@ namespace cur_ofs ++; } emit_literal_as_bytes(le[i], repr->fields[i].ty, out_relocations, base_ofs + cur_ofs); - size_t size; - assert(Target_GetSizeOf(sp, m_resolve, repr->fields[i].ty, size)); + size_t size = Target_GetSizeOf_Required(sp, m_resolve, repr->fields[i].ty); cur_ofs += size; } while(cur_ofs < repr->size) @@ -898,8 +905,7 @@ namespace emit_literal_as_bytes(*le.val, repr->fields[le.idx].ty, out_relocations, base_ofs + cur_ofs); - size_t size; - assert(Target_GetSizeOf(sp, m_resolve, repr->fields[le.idx].ty, size)); + size_t size = Target_GetSizeOf_Required(sp, m_resolve, repr->fields[le.idx].ty); cur_ofs += size; } @@ -914,8 +920,7 @@ namespace auto v = ::HIR::Literal::make_Integer(le.idx); emit_literal_as_bytes(v, repr->fields[ve->field.index].ty, out_relocations, base_ofs + cur_ofs); - size_t size; - assert(Target_GetSizeOf(sp, m_resolve, repr->fields[ve->field.index].ty, size)); + size_t size = Target_GetSizeOf_Required(sp, m_resolve, repr->fields[ve->field.index].ty); cur_ofs += size; } // TODO: Nonzero? @@ -989,8 +994,7 @@ namespace for(const auto& v : lit.as_List()) { emit_literal_as_bytes(v, *te.inner, out_relocations, base_ofs); - size_t size; - assert(Target_GetSizeOf(sp, m_resolve, *te.inner, size)); + size_t size = Target_GetSizeOf(sp, m_resolve, *te.inner, size); base_ofs += size; } } break; diff --git a/src/trans/target.cpp b/src/trans/target.cpp index 5f52912e..9172481a 100644 --- a/src/trans/target.cpp +++ b/src/trans/target.cpp @@ -17,22 +17,32 @@ const TargetArch ARCH_X86_64 = { "x86_64", 64, false, - { /*atomic(u8)=*/true, false, true, true, true } + TargetArch::Atomics(/*atomic(u8)=*/true, false, true, true, true), + TargetArch::Alignments(2, 4, 8, 16, 4, 8, 8) }; const TargetArch ARCH_X86 = { "x86", 32, false, - { /*atomic(u8)=*/true, false, true, false, true } + { /*atomic(u8)=*/true, false, true, false, true }, + TargetArch::Alignments(2, 4, /*u64*/4, /*u128*/4, 4, 4, /*ptr*/4) // u128 has the same alignment as u64, which is u32's alignment. And f64 is 4 byte aligned }; const TargetArch ARCH_ARM64 = { "aarch64", 64, false, - { /*atomic(u8)=*/true, true, true, true, true } + { /*atomic(u8)=*/true, true, true, true, true }, + TargetArch::Alignments(2, 4, 8, 16, 4, 8, 8) }; const TargetArch ARCH_ARM32 = { "arm", 32, false, - { /*atomic(u8)=*/true, false, true, false, true } + { /*atomic(u8)=*/true, false, true, false, true }, + TargetArch::Alignments(2, 4, 8, 16, 4, 8, 4) // Note, all types are natively aligned (but i128 will be emulated) +}; +const TargetArch ARCH_M68K = { + "m68k", + 32, true, + { /*atomic(u8)=*/true, false, true, false, true }, + TargetArch::Alignments(2, 2, 2, 2, 2, 2, 2) }; TargetSpec g_target; @@ -108,6 +118,10 @@ namespace { rv.m_arch = ARCH_X86_64; } + else if( key_val.value.as_string() == ARCH_M68K.m_name ) + { + rv.m_arch = ARCH_M68K; + } else { // Error. @@ -150,6 +164,11 @@ namespace check_path_length(key_val, 3); rv.m_backend_c.m_c_compiler = key_val.value.as_string(); } + else if( key_val.path[2] == "emulate-i128" ) + { + check_path_length(key_val, 3); + rv.m_backend_c.m_emulated_i128 = key_val.value.as_bool(); + } else if( key_val.path[2] == "compiler-opts" ) { check_path_length(key_val, 3); @@ -224,6 +243,42 @@ namespace check_path_length(key_val, 2); rv.m_arch.m_atomics.ptr = key_val.value.as_bool(); } + else if( key_val.path[1] == "alignments" ) + { + check_path_length(key_val, 3); + if( key_val.path[2] == "u16" ) + { + rv.m_arch.m_alignments.u16 = key_val.value.as_int(); + } + else if( key_val.path[2] == "u32" ) + { + rv.m_arch.m_alignments.u32 = key_val.value.as_int(); + } + else if( key_val.path[2] == "u64" ) + { + rv.m_arch.m_alignments.u64 = key_val.value.as_int(); + } + else if( key_val.path[2] == "u128" ) + { + rv.m_arch.m_alignments.u128 = key_val.value.as_int(); + } + else if( key_val.path[2] == "f32" ) + { + rv.m_arch.m_alignments.f32 = key_val.value.as_int(); + } + else if( key_val.path[2] == "f64" ) + { + rv.m_arch.m_alignments.f64 = key_val.value.as_int(); + } + else if( key_val.path[2] == "ptr" ) + { + rv.m_arch.m_alignments.ptr = key_val.value.as_int(); + } + else + { + ::std::cerr << "WARNING: Unknown field arch.alignments." << key_val.path[1] << " in " << filename << ::std::endl; + } + } else { ::std::cerr << "WARNING: Unknown field arch." << key_val.path[1] << " in " << filename << ::std::endl; @@ -281,10 +336,10 @@ namespace << "[backend.c]\n" << "variant = \"" << H::c_variant_name(spec.m_backend_c.m_codegen_mode) << "\"\n" << "target = \"" << spec.m_backend_c.m_c_compiler << "\"\n" - << "compiler-opts = [" << spec.m_backend_c.m_compiler_opts << "]\n" - << "linker-opts = [" << spec.m_backend_c.m_linker_opts << "]\n" + << "compiler-opts = ["; for(const auto& s : spec.m_backend_c.m_compiler_opts) of << "\"" << s << "\","; of << "]\n" + << "linker-opts = ["; for(const auto& s : spec.m_backend_c.m_linker_opts) of << "\"" << s << "\","; of << "]\n" << "\n" - << "[arch]" + << "[arch]\n" << "name = \"" << spec.m_arch.m_name << "\"\n" << "pointer-bits = " << spec.m_arch.m_pointer_bits << "\n" << "is-big-endian = " << H::tfstr(spec.m_arch.m_big_endian) << "\n" @@ -293,6 +348,16 @@ namespace << "has-atomic-u32 = " << H::tfstr(spec.m_arch.m_atomics.u32) << "\n" << "has-atomic-u64 = " << H::tfstr(spec.m_arch.m_atomics.u64) << "\n" << "has-atomic-ptr = " << H::tfstr(spec.m_arch.m_atomics.ptr) << "\n" + << "alignments = {" + << " u16 = " << static_cast<int>(spec.m_arch.m_alignments.u16 ) << "," + << " u32 = " << static_cast<int>(spec.m_arch.m_alignments.u32 ) << "," + << " u64 = " << static_cast<int>(spec.m_arch.m_alignments.u64 ) << "," + << " u128 = " << static_cast<int>(spec.m_arch.m_alignments.u128) << "," + << " f32 = " << static_cast<int>(spec.m_arch.m_alignments.f32 ) << "," + << " f64 = " << static_cast<int>(spec.m_arch.m_alignments.f64 ) << "," + << " ptr = " << static_cast<int>(spec.m_arch.m_alignments.ptr ) + << " }\n" + << "\n" ; } TargetSpec init_from_spec_name(const ::std::string& target_name) @@ -307,42 +372,49 @@ namespace else if(target_name == "i586-linux-gnu") { return TargetSpec { - "unix", "linux", "gnu", {CodegenMode::Gnu11, "i586-linux-gnu", BACKEND_C_OPTS_GNU}, + "unix", "linux", "gnu", {CodegenMode::Gnu11, true, "i586-linux-gnu", BACKEND_C_OPTS_GNU}, ARCH_X86 }; } else if(target_name == "x86_64-linux-gnu") { return TargetSpec { - "unix", "linux", "gnu", {CodegenMode::Gnu11, "x86_64-linux-gnu", BACKEND_C_OPTS_GNU}, + "unix", "linux", "gnu", {CodegenMode::Gnu11, false, "x86_64-linux-gnu", BACKEND_C_OPTS_GNU}, ARCH_X86_64 }; } else if(target_name == "arm-linux-gnu") { return TargetSpec { - "unix", "linux", "gnu", {CodegenMode::Gnu11, "arm-elf-eabi", BACKEND_C_OPTS_GNU}, + "unix", "linux", "gnu", {CodegenMode::Gnu11, true, "arm-elf-eabi", BACKEND_C_OPTS_GNU}, ARCH_ARM32 }; } else if(target_name == "aarch64-linux-gnu") { return TargetSpec { - "unix", "linux", "gnu", {CodegenMode::Gnu11, "aarch64-linux-gnu", BACKEND_C_OPTS_GNU}, + "unix", "linux", "gnu", {CodegenMode::Gnu11, false, "aarch64-linux-gnu", BACKEND_C_OPTS_GNU}, ARCH_ARM64 }; } + else if(target_name == "m68k-linux-gnu") + { + return TargetSpec { + "unix", "linux", "gnu", {CodegenMode::Gnu11, true, "m68k-linux-gnu", BACKEND_C_OPTS_GNU}, + ARCH_M68K + }; + } else if(target_name == "i586-windows-gnu") { return TargetSpec { - "windows", "windows", "gnu", {CodegenMode::Gnu11, "mingw32", BACKEND_C_OPTS_GNU}, + "windows", "windows", "gnu", {CodegenMode::Gnu11, true, "mingw32", BACKEND_C_OPTS_GNU}, ARCH_X86 }; } else if(target_name == "x86_64-windows-gnu") { return TargetSpec { - "windows", "windows", "gnu", {CodegenMode::Gnu11, "x86_64-w64-mingw32", BACKEND_C_OPTS_GNU}, + "windows", "windows", "gnu", {CodegenMode::Gnu11, false, "x86_64-w64-mingw32", BACKEND_C_OPTS_GNU}, ARCH_X86_64 }; } @@ -350,84 +422,84 @@ namespace { // TODO: Should this include the "kernel32.lib" inclusion? return TargetSpec { - "windows", "windows", "msvc", {CodegenMode::Msvc, "x86", {}, {}}, + "windows", "windows", "msvc", {CodegenMode::Msvc, true, "x86", {}, {}}, ARCH_X86 }; } else if (target_name == "x86_64-windows-msvc") { return TargetSpec { - "windows", "windows", "msvc", {CodegenMode::Msvc, "amd64", {}, {}}, + "windows", "windows", "msvc", {CodegenMode::Msvc, true, "amd64", {}, {}}, ARCH_X86_64 }; } else if(target_name == "i686-unknown-freebsd") { return TargetSpec { - "unix", "freebsd", "gnu", {CodegenMode::Gnu11, "i686-unknown-freebsd", BACKEND_C_OPTS_GNU}, + "unix", "freebsd", "gnu", {CodegenMode::Gnu11, true, "i686-unknown-freebsd", BACKEND_C_OPTS_GNU}, ARCH_X86 }; } else if(target_name == "x86_64-unknown-freebsd") { return TargetSpec { - "unix", "freebsd", "gnu", {CodegenMode::Gnu11, "x86_64-unknown-freebsd", BACKEND_C_OPTS_GNU}, + "unix", "freebsd", "gnu", {CodegenMode::Gnu11, false, "x86_64-unknown-freebsd", BACKEND_C_OPTS_GNU}, ARCH_X86_64 }; } else if(target_name == "arm-unknown-freebsd") { return TargetSpec { - "unix", "freebsd", "gnu", {CodegenMode::Gnu11, "arm-unknown-freebsd", BACKEND_C_OPTS_GNU}, + "unix", "freebsd", "gnu", {CodegenMode::Gnu11, true, "arm-unknown-freebsd", BACKEND_C_OPTS_GNU}, ARCH_ARM32 }; } else if(target_name == "aarch64-unknown-freebsd") { return TargetSpec { - "unix", "freebsd", "gnu", {CodegenMode::Gnu11, "aarch64-unknown-freebsd", BACKEND_C_OPTS_GNU}, + "unix", "freebsd", "gnu", {CodegenMode::Gnu11, false, "aarch64-unknown-freebsd", BACKEND_C_OPTS_GNU}, ARCH_ARM64 }; } else if(target_name == "x86_64-unknown-netbsd") { return TargetSpec { - "unix", "netbsd", "gnu", {CodegenMode::Gnu11, "x86_64-unknown-netbsd", BACKEND_C_OPTS_GNU}, + "unix", "netbsd", "gnu", {CodegenMode::Gnu11, false, "x86_64-unknown-netbsd", BACKEND_C_OPTS_GNU}, ARCH_X86_64 }; } else if(target_name == "i686-unknown-openbsd") { return TargetSpec { - "unix", "openbsd", "gnu", {CodegenMode::Gnu11, "i686-unknown-openbsd", BACKEND_C_OPTS_GNU}, + "unix", "openbsd", "gnu", {CodegenMode::Gnu11, true, "i686-unknown-openbsd", BACKEND_C_OPTS_GNU}, ARCH_X86 }; } else if(target_name == "x86_64-unknown-openbsd") { return TargetSpec { - "unix", "openbsd", "gnu", {CodegenMode::Gnu11, "x86_64-unknown-openbsd", BACKEND_C_OPTS_GNU}, + "unix", "openbsd", "gnu", {CodegenMode::Gnu11, false, "x86_64-unknown-openbsd", BACKEND_C_OPTS_GNU}, ARCH_X86_64 }; } else if(target_name == "arm-unknown-openbsd") { return TargetSpec { - "unix", "openbsd", "gnu", {CodegenMode::Gnu11, "arm-unknown-openbsd", BACKEND_C_OPTS_GNU}, + "unix", "openbsd", "gnu", {CodegenMode::Gnu11, true, "arm-unknown-openbsd", BACKEND_C_OPTS_GNU}, ARCH_ARM32 }; } else if(target_name == "aarch64-unknown-openbsd") { return TargetSpec { - "unix", "openbsd", "gnu", {CodegenMode::Gnu11, "aarch64-unknown-openbsd", BACKEND_C_OPTS_GNU}, + "unix", "openbsd", "gnu", {CodegenMode::Gnu11, false, "aarch64-unknown-openbsd", BACKEND_C_OPTS_GNU}, ARCH_ARM64 }; } else if(target_name == "x86_64-unknown-dragonfly") { return TargetSpec { - "unix", "dragonfly", "gnu", {CodegenMode::Gnu11, "x86_64-unknown-dragonfly", BACKEND_C_OPTS_GNU}, + "unix", "dragonfly", "gnu", {CodegenMode::Gnu11, false, "x86_64-unknown-dragonfly", BACKEND_C_OPTS_GNU}, ARCH_X86_64 }; } @@ -435,7 +507,21 @@ namespace { // NOTE: OSX uses Mach-O binaries, which don't fully support the defaults used for GNU targets return TargetSpec { - "unix", "macos", "gnu", {CodegenMode::Gnu11, "x86_64-apple-darwin", {}, {}}, + "unix", "macos", "gnu", {CodegenMode::Gnu11, false, "x86_64-apple-darwin", {}, {}}, + ARCH_X86_64 + }; + } + else if(target_name == "arm-unknown-haiku") + { + return TargetSpec { + "unix", "haiku", "gnu", {CodegenMode::Gnu11, true, "arm-unknown-haiku", {}, {}}, + ARCH_ARM32 + }; + } + else if(target_name == "x86_64-unknown-haiku") + { + return TargetSpec { + "unix", "haiku", "gnu", {CodegenMode::Gnu11, false, "x86_64-unknown-haiku", {}, {}}, ARCH_X86_64 }; } @@ -536,48 +622,45 @@ bool Target_GetSizeAndAlignOf(const Span& sp, const StaticTraitResolve& resolve, case ::HIR::CoreType::U8: case ::HIR::CoreType::I8: out_size = 1; - out_align = 1; + out_align = 1; // u8 is always 1 aligned return true; case ::HIR::CoreType::U16: case ::HIR::CoreType::I16: out_size = 2; - out_align = 2; + out_align = g_target.m_arch.m_alignments.u16; return true; case ::HIR::CoreType::U32: case ::HIR::CoreType::I32: case ::HIR::CoreType::Char: out_size = 4; - out_align = 4; + out_align = g_target.m_arch.m_alignments.u32; return true; case ::HIR::CoreType::U64: case ::HIR::CoreType::I64: out_size = 8; - // TODO: on x86, u64/i64 has an alignment of 4, while x86_64 has 8. What do other platforms have? - out_align = g_target.m_arch.m_name == "x86" ? 4 : 8; + out_align = g_target.m_arch.m_alignments.u64; return true; case ::HIR::CoreType::U128: case ::HIR::CoreType::I128: out_size = 16; // TODO: If i128 is emulated, this can be 8 (as it is on x86, where it's actually 4 due to the above comment) - if( g_target.m_arch.m_name == "x86" ) - out_align = 4; - else if( /*g_target.m_arch.m_name == "x86_64" && */g_target.m_backend_c.m_codegen_mode == CodegenMode::Msvc ) - out_align = 8; - else - out_align = 16; + if( g_target.m_backend_c.m_emulated_i128 ) + out_align = g_target.m_arch.m_alignments.u64; + else + out_align = g_target.m_arch.m_alignments.u128; return true; case ::HIR::CoreType::Usize: case ::HIR::CoreType::Isize: out_size = g_target.m_arch.m_pointer_bits / 8; - out_align = g_target.m_arch.m_pointer_bits / 8; + out_align = g_target.m_arch.m_alignments.ptr; return true; case ::HIR::CoreType::F32: out_size = 4; - out_align = 4; + out_align = g_target.m_arch.m_alignments.f32; return true; case ::HIR::CoreType::F64: out_size = 8; - out_align = g_target.m_arch.m_name == "x86" ? 4 : 8; + out_align = g_target.m_arch.m_alignments.f64; return true; case ::HIR::CoreType::Str: DEBUG("sizeof on a `str` - unsized"); diff --git a/src/trans/target.hpp b/src/trans/target.hpp index 107d19e1..3433483b 100644 --- a/src/trans/target.hpp +++ b/src/trans/target.hpp @@ -17,23 +17,53 @@ enum class CodegenMode Msvc, }; +// NOTE: The default architecture is an unnamed 32-bit little-endian arch with all types natively aligned struct TargetArch { ::std::string m_name; unsigned m_pointer_bits; bool m_big_endian; - struct { - bool u8; - bool u16; - bool u32; - bool u64; - bool ptr; + struct Atomics { + bool u8 = true; + bool u16 = true; + bool u32 = true; + bool u64 = false; + bool ptr = true; + Atomics(bool u8 = true, bool u16 = true, bool u32 = true, bool u64 = false, bool ptr = true) + :u8(u8) + ,u16(u16) + ,u32(u32) + ,u64(u64) + ,ptr(ptr) + { + } } m_atomics; + + struct Alignments { + uint8_t u16; + uint8_t u32; + uint8_t u64; + uint8_t u128; + uint8_t f32; + uint8_t f64; + uint8_t ptr; + Alignments(uint8_t u16 = 2, uint8_t u32 = 4, uint8_t u64 = 8, uint8_t u128 = 16, uint8_t f32 = 4, uint8_t f64 = 8, uint8_t ptr = 4) + :u16 (u16) + ,u32 (u32 ) + ,u64 (u64 ) + ,u128(u128) + ,f32 (f32 ) + ,f64 (f64 ) + ,ptr (ptr ) + { + } + } m_alignments; }; struct BackendOptsC { CodegenMode m_codegen_mode; + bool m_emulated_i128; // Influences the chosen alignment for i128/u128 ::std::string m_c_compiler; // MSVC arch / GNU triplet ::std::vector< ::std::string> m_compiler_opts; ::std::vector< ::std::string> m_linker_opts; |