diff options
Diffstat (limited to 'src/trans')
-rw-r--r-- | src/trans/codegen_c.cpp | 24 | ||||
-rw-r--r-- | src/trans/target.cpp | 67 |
2 files changed, 67 insertions, 24 deletions
diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp index 0171f19f..5df20334 100644 --- a/src/trans/codegen_c.cpp +++ b/src/trans/codegen_c.cpp @@ -559,12 +559,24 @@ namespace { switch( m_compiler ) { case Compiler::Gcc: - if( getenv("CC") ) { - args.push_back( getenv("CC") ); - } - else { - //args.push_back( Target_GetCurSpec().m_c_compiler + "-gcc" ); - args.push_back( "gcc" ); + // Pick the compiler + // - from `CC-${TRIPLE}` environment variable + // - from the $CC environment variable + // - `gcc-${TRIPLE}` (if available) + // - `gcc` as fallback + { + ::std::string varname = "CC-" + Target_GetCurSpec().m_c_compiler; + if( getenv(varname.c_str()) ) { + args.push_back( getenv(varname.c_str()) ); + } + 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_c_compiler + "-gcc" ); + //args.push_back( "gcc" ); + } } args.push_back("-ffunction-sections"); args.push_back("-pthread"); diff --git a/src/trans/target.cpp b/src/trans/target.cpp index 2bf655a9..81dc8c0c 100644 --- a/src/trans/target.cpp +++ b/src/trans/target.cpp @@ -54,7 +54,18 @@ namespace auto check_path_length = [&](const TomlKeyValue& kv, unsigned len) { if( kv.path.size() != len ) { - // TODO: Error. + if( kv.path.size() > len ) { + ::std::cerr << "ERROR: Unexpected sub-node to " << kv.path << " in " << filename << ::std::endl; + } + else { + ::std::cerr << "ERROR: Expected sub-nodes in " << kv.path << " in " << filename << ::std::endl; + } + exit(1); + } + }; + auto check_path_length_min = [&](const TomlKeyValue& kv, unsigned len) { + if( kv.path.size() < len ) { + ::std::cerr << "ERROR: Expected sub-nodes in " << kv.path << " in " << filename << ::std::endl; } }; @@ -62,6 +73,7 @@ namespace { if( key_val.path[0] == "target" ) { + check_path_length_min(key_val, 2); if( key_val.path[1] == "family" ) { check_path_length(key_val, 2); @@ -77,11 +89,6 @@ namespace check_path_length(key_val, 2); rv.m_env_name = key_val.value.as_string(); } - else if( key_val.path[1] == "env-name" ) - { - check_path_length(key_val, 2); - rv.m_env_name = key_val.value.as_string(); - } else if( key_val.path[1] == "arch" ) { check_path_length(key_val, 2); @@ -103,22 +110,23 @@ namespace } else { - // TODO: Error. + // Error. + ::std::cerr << "ERROR: Unknown architecture name '" << key_val.value.as_string() << "' in " << filename << ::std::endl; + exit(1); } } else { - // TODO: Error/warning + // Warning + ::std::cerr << "Warning: Unknown configuration item " << key_val.path[0] << "." << key_val.path[1] << " in " << filename << ::std::endl; } } else if( key_val.path[0] == "backend" ) { + check_path_length_min(key_val, 2); if( key_val.path[1] == "c" ) { - if( key_val.path.size() <= 2 ) { - // TODO: Error. - continue ; - } + check_path_length_min(key_val, 3); if( key_val.path[2] == "variant" ) { @@ -133,7 +141,8 @@ namespace } else { - // TODO: Error. + ::std::cerr << "ERROR: Unknown C variant name '" << key_val.value.as_string() << "' in " << filename << ::std::endl; + exit(1); } } else if( key_val.path[2] == "target" ) @@ -143,71 +152,90 @@ namespace } else { - // TODO: Warning/error + ::std::cerr << "WARNING: Unknown field backend.c." << key_val.path[2] << " in " << filename << ::std::endl; } } // Does MMIR need configuration? else { - // TODO: Error/warning + ::std::cerr << "WARNING: Unknown configuration item backend." << key_val.path[1] << " in " << filename << ::std::endl; } } else if( key_val.path[0] == "arch" ) { + check_path_length_min(key_val, 2); if( key_val.path[1] == "name" ) { + check_path_length(key_val, 2); + if( rv.m_arch.m_name != "" ) { + ::std::cerr << "ERROR: Architecture already specified to be '" << rv.m_arch.m_name << "'" << ::std::endl; + exit(1); + } rv.m_arch.m_name = key_val.value.as_string(); } else if( key_val.path[1] == "pointer-bits" ) { + check_path_length(key_val, 2); rv.m_arch.m_pointer_bits = key_val.value.as_int(); } else if( key_val.path[1] == "is-big-endian" ) { + check_path_length(key_val, 2); rv.m_arch.m_big_endian = key_val.value.as_bool(); } else if( key_val.path[1] == "has-atomic-u8" ) { + check_path_length(key_val, 2); rv.m_arch.m_atomics.u8 = key_val.value.as_bool(); } else if( key_val.path[1] == "has-atomic-u16" ) { + check_path_length(key_val, 2); rv.m_arch.m_atomics.u16 = key_val.value.as_bool(); } else if( key_val.path[1] == "has-atomic-u32" ) { + check_path_length(key_val, 2); rv.m_arch.m_atomics.u32 = key_val.value.as_bool(); } else if( key_val.path[1] == "has-atomic-u64" ) { + check_path_length(key_val, 2); rv.m_arch.m_atomics.u64 = key_val.value.as_bool(); } else if( key_val.path[1] == "has-atomic-ptr" ) { + check_path_length(key_val, 2); rv.m_arch.m_atomics.ptr = key_val.value.as_bool(); } else { - // TODO: warning/error + ::std::cerr << "WARNING: Unknown field arch." << key_val.path[1] << " in " << filename << ::std::endl; } } else { + ::std::cerr << "WARNING: Unknown configuration item " << key_val.path[0] << " in " << filename << ::std::endl; } } catch(const TomlValue::TypeError& e) { - // TODO: error + ::std::cerr << "ERROR: Invalid type for " << key_val.path << " - " << e << ::std::endl; + exit(1); } } // TODO: Ensure that everything is set + if( rv.m_arch.m_name == "" ) { + ::std::cerr << "ERROR: Architecture not specified in " << filename << ::std::endl; + exit(1); + } return rv; } TargetSpec init_from_spec_name(const ::std::string& target_name) { - // TODO: If there's a '/' or a '\' in the filename, open it as a path, otherwise it has to be a triple. + // If there's a '/' or a '\' in the filename, open it as a path, otherwise assume it's a triple. if( target_name.find('/') != ::std::string::npos || target_name.find('\\') != ::std::string::npos ) { return load_spec_from_file(target_name); @@ -355,6 +383,9 @@ void Target_SetCfg(const ::std::string& target_name) Cfg_SetValue("target_arch", g_target.m_arch.m_name); Cfg_SetValueCb("target_has_atomic", [&](const ::std::string& s) { if(s == "8") return g_target.m_arch.m_atomics.u8; // Has an atomic byte + if(s == "16") return g_target.m_arch.m_atomics.u16; + if(s == "32") return g_target.m_arch.m_atomics.u32; + if(s == "64") return g_target.m_arch.m_atomics.u64; if(s == "ptr") return g_target.m_arch.m_atomics.ptr; // Has an atomic pointer-sized value return false; }); |