summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/trans/target.cpp172
1 files changed, 165 insertions, 7 deletions
diff --git a/src/trans/target.cpp b/src/trans/target.cpp
index 1f04666e..54c3e7df 100644
--- a/src/trans/target.cpp
+++ b/src/trans/target.cpp
@@ -12,18 +12,19 @@
#include <map>
#include <hir/hir.hpp>
#include <hir_typeck/helpers.hpp>
+#include <toml.h> // tools/common
-TargetArch ARCH_X86_64 = {
+const TargetArch ARCH_X86_64 = {
"x86_64",
64, false,
{ /*atomic(u8)=*/true, false, true, true, true }
};
-TargetArch ARCH_X86 = {
+const TargetArch ARCH_X86 = {
"x86",
32, false,
{ /*atomic(u8)=*/true, false, true, false, true }
};
-TargetArch ARCH_ARM32 = {
+const TargetArch ARCH_ARM32 = {
"arm",
32, false,
{ /*atomic(u8)=*/true, false, true, false, true }
@@ -37,25 +38,182 @@ namespace
{
TargetSpec load_spec_from_file(const ::std::string& filename)
{
- throw "";
+ TargetSpec rv;
+
+ TomlFile toml_file(filename);
+ for(auto key_val : toml_file)
+ {
+ // Assertion: The way toml works, there has to be at least two entries in every path.
+ assert(key_val.path.size() > 1);
+ DEBUG(key_val.path << " = " << key_val.value);
+
+ auto check_path_length = [&](const TomlKeyValue& kv, unsigned len) {
+ if( kv.path.size() != len ) {
+ // TODO: Error.
+ }
+ };
+
+ try
+ {
+ if( key_val.path[0] == "target" )
+ {
+ if( key_val.path[1] == "family" )
+ {
+ check_path_length(key_val, 2);
+ rv.m_family = key_val.value.as_string();
+ }
+ else if( key_val.path[1] == "os-name" )
+ {
+ check_path_length(key_val, 2);
+ rv.m_os_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] == "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);
+ if( key_val.value.as_string() == ARCH_ARM32.m_name )
+ {
+ rv.m_arch = ARCH_ARM32;
+ }
+ else if( key_val.value.as_string() == ARCH_X86.m_name )
+ {
+ rv.m_arch = ARCH_X86;
+ }
+ else if( key_val.value.as_string() == ARCH_X86_64.m_name )
+ {
+ rv.m_arch = ARCH_X86_64;
+ }
+ else
+ {
+ // TODO: Error.
+ }
+ }
+ else
+ {
+ // TODO: Error/warning
+ }
+ }
+ else if( key_val.path[0] == "backend" )
+ {
+ if( key_val.path[1] == "c" )
+ {
+ if( key_val.path.size() <= 2 ) {
+ // TODO: Error.
+ continue ;
+ }
+
+ if( key_val.path[2] == "variant" )
+ {
+ check_path_length(key_val, 3);
+ if( key_val.value.as_string() == "msvc" )
+ {
+ rv.m_codegen_mode = CodegenMode::Msvc;
+ }
+ else if( key_val.value.as_string() == "gnu" )
+ {
+ rv.m_codegen_mode = CodegenMode::Gnu11;
+ }
+ else
+ {
+ // TODO: Error.
+ }
+ }
+ else if( key_val.path[2] == "target" )
+ {
+ check_path_length(key_val, 3);
+ rv.m_c_compiler = key_val.value.as_string();
+ }
+ else
+ {
+ // TODO: Warning/error
+ }
+ }
+ // Does MMIR need configuration?
+ else
+ {
+ // TODO: Error/warning
+ }
+ }
+ else if( key_val.path[0] == "arch" )
+ {
+ if( key_val.path[1] == "name" )
+ {
+ rv.m_arch.m_name = key_val.value.as_string();
+ }
+ else if( key_val.path[1] == "pointer-bits" )
+ {
+ rv.m_arch.m_pointer_bits = key_val.value.as_int();
+ }
+ else if( key_val.path[1] == "is-big-endian" )
+ {
+ rv.m_arch.m_big_endian = key_val.value.as_bool();
+ }
+ else if( key_val.path[1] == "has-atomic-u8" )
+ {
+ rv.m_arch.m_atomics.u8 = key_val.value.as_bool();
+ }
+ else if( key_val.path[1] == "has-atomic-u16" )
+ {
+ rv.m_arch.m_atomics.u16 = key_val.value.as_bool();
+ }
+ else if( key_val.path[1] == "has-atomic-u32" )
+ {
+ rv.m_arch.m_atomics.u32 = key_val.value.as_bool();
+ }
+ else if( key_val.path[1] == "has-atomic-u64" )
+ {
+ rv.m_arch.m_atomics.u64 = key_val.value.as_bool();
+ }
+ else if( key_val.path[1] == "has-atomic-ptr" )
+ {
+ rv.m_arch.m_atomics.ptr = key_val.value.as_bool();
+ }
+ else
+ {
+ // TODO: warning/error
+ }
+ }
+ else
+ {
+ }
+ }
+ catch(const TomlValue::TypeError& e)
+ {
+ // TODO: error
+ }
+ }
+
+ // TODO: Ensure that everything is set
+
+ return rv;
}
TargetSpec init_from_spec_name(const ::std::string& target_name)
{
- if( ::std::ifstream(target_name).is_open() )
+ // TODO: If there's a '/' or a '\' in the filename, open it as a path, otherwise it has to be a triple.
+ if( target_name.find('/') != ::std::string::npos || target_name.find('\\') != ::std::string::npos )
{
return load_spec_from_file(target_name);
}
else if(target_name == "i586-linux-gnu")
{
return TargetSpec {
- "unix", "linux", "gnu", CodegenMode::Gnu11, "i586-pc-linux-gnu",
+ "unix", "linux", "gnu", CodegenMode::Gnu11, "i586-linux-gnu",
ARCH_X86
};
}
else if(target_name == "x86_64-linux-gnu")
{
return TargetSpec {
- "unix", "linux", "gnu", CodegenMode::Gnu11, "x86_64-pc-linux-gnu",
+ "unix", "linux", "gnu", CodegenMode::Gnu11, "x86_64-linux-gnu",
ARCH_X86_64
};
}