From ad1cec3df31470a1b97f1c672a45ae57495945a5 Mon Sep 17 00:00:00 2001 From: John Paul Adrian Glaubitz Date: Wed, 14 Nov 2018 12:33:24 +0100 Subject: Trans - Add initial support for m68k --- src/trans/target.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src/trans/target.cpp') diff --git a/src/trans/target.cpp b/src/trans/target.cpp index f91b679a..64cf19c6 100644 --- a/src/trans/target.cpp +++ b/src/trans/target.cpp @@ -34,6 +34,11 @@ const TargetArch ARCH_ARM32 = { 32, false, { /*atomic(u8)=*/true, false, true, false, true } }; +const TargetArch ARCH_M68K = { + "m68k", + 32, true, + { /*atomic(u8)=*/true, false, true, false, true } +}; TargetSpec g_target; @@ -108,6 +113,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. @@ -332,6 +341,13 @@ namespace ARCH_ARM64 }; } + else if(target_name == "m68k-linux-gnu") + { + return TargetSpec { + "unix", "linux", "gnu", {CodegenMode::Gnu11, "m68k-linux-gnu", BACKEND_C_OPTS_GNU}, + ARCH_M68K + }; + } else if(target_name == "i586-windows-gnu") { return TargetSpec { -- cgit v1.2.3 From f6209dce15ce863e15dc3063d78e43eeb0db25ee Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 15 Dec 2018 14:47:08 +0800 Subject: Targets - Add alignment to the target specs, along with a saveback test. --- Makefile | 9 ++- samples/target_stress_test.toml | 22 +++++++ src/main.cpp | 32 ++++++++-- src/trans/codegen_c.cpp | 11 ++-- src/trans/target.cpp | 137 ++++++++++++++++++++++++++++------------ src/trans/target.hpp | 28 +++++--- tools/common/toml.cpp | 85 ++++++++++++++++--------- tools/common/toml.h | 21 +++++- 8 files changed, 252 insertions(+), 93 deletions(-) create mode 100644 samples/target_stress_test.toml (limited to 'src/trans/target.cpp') diff --git a/Makefile b/Makefile index 1eda93dd..23c799d2 100644 --- a/Makefile +++ b/Makefile @@ -276,7 +276,14 @@ output/rust/test_run-pass_hello_out.txt: output/rust/test_run-pass_hello # # TEST: Rust standard library and the "hello, world" run-pass test # -test: output/libstd.hir output/rust/test_run-pass_hello_out.txt $(BIN) +test: output/libstd.hir output/rust/test_run-pass_hello_out.txt $(BIN) TEST_targetsaveback + +.PHONY: TEST_targetsaveback +TEST_targetsaveback: + $(BIN) --target ./samples/target_stress_test.toml --dump-target-spec TMP-dump-target_stress_test.toml + $(BIN) --target ./TMP-dump-target_stress_test.toml --dump-target-spec TMP-dump-target_stress_test-2.toml + diff ./samples/target_stress_test.toml TMP-dump-target_stress_test.toml + diff TMP-dump-target_stress_test.toml TMP-dump-target_stress_test-2.toml # # TEST: Attempt to compile rust_os (Tifflin) from ../rust_os diff --git a/samples/target_stress_test.toml b/samples/target_stress_test.toml new file mode 100644 index 00000000..c7630567 --- /dev/null +++ b/samples/target_stress_test.toml @@ -0,0 +1,22 @@ +[target] +family = "fake" +os-name = "fakest" +env-name = "faker" + +[backend.c] +variant = "msvc" +target = "x86_64-linux-msvc" +compiler-opts = ["/W:1234",] +linker-opts = ["/K",] + +[arch] +name = "fubar" +pointer-bits = 128 +is-big-endian = true +has-atomic-u8 = false +has-atomic-u16 = false +has-atomic-u32 = false +has-atomic-u64 = false +has-atomic-ptr = false +alignments = { u16 = 1, u32 = 2, u64 = 4, u128 = 8, f32 = 3, f64 = 5, ptr = 16 } + diff --git a/src/main.cpp b/src/main.cpp index 2dd05a05..a50fe095 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -36,6 +36,7 @@ bool g_debug_enabled = true; 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" ); @@ -156,6 +157,9 @@ struct ProgramParams bool test_harness = false; + // NOTE: If populated, nothing happens except for loading the target + ::std::string target_saveback; + ::std::vector lib_search_dirs; ::std::vector libraries; ::std::map<::std::string, ::std::string> crate_overrides; // --extern name=path @@ -214,8 +218,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 ) { @@ -1060,6 +1077,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; } @@ -1070,12 +1094,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_DUMP") ) { while( a[0] ) diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp index 55b3ea1a..84a538d5 100644 --- a/src/trans/codegen_c.cpp +++ b/src/trans/codegen_c.cpp @@ -205,20 +205,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; } diff --git a/src/trans/target.cpp b/src/trans/target.cpp index 64cf19c6..332a7e04 100644 --- a/src/trans/target.cpp +++ b/src/trans/target.cpp @@ -17,27 +17,32 @@ const TargetArch ARCH_X86_64 = { "x86_64", 64, false, - { /*atomic(u8)=*/true, false, true, true, true } + { /*atomic(u8)=*/true, false, true, true, true }, + { 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 }, + { 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 }, + { 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 }, + { 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 } + { /*atomic(u8)=*/true, false, true, false, true }, + { 2, 4, 8, 16, 4, 8, 4 } // TODO: Does m68k have lower alignments? }; TargetSpec g_target; @@ -159,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); @@ -233,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; @@ -290,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" @@ -302,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(spec.m_arch.m_alignments.u16 ) << "," + << " u32 = " << static_cast(spec.m_arch.m_alignments.u32 ) << "," + << " u64 = " << static_cast(spec.m_arch.m_alignments.u64 ) << "," + << " u128 = " << static_cast(spec.m_arch.m_alignments.u128) << "," + << " f32 = " << static_cast(spec.m_arch.m_alignments.f32 ) << "," + << " f64 = " << static_cast(spec.m_arch.m_alignments.f64 ) << "," + << " ptr = " << static_cast(spec.m_arch.m_alignments.ptr ) + << " }\n" + << "\n" ; } TargetSpec init_from_spec_name(const ::std::string& target_name) @@ -316,49 +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, "m68k-linux-gnu", BACKEND_C_OPTS_GNU}, + "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 }; } @@ -366,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 }; } @@ -451,7 +507,7 @@ 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 }; } @@ -684,48 +740,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 b1ed9456..b6f04a42 100644 --- a/src/trans/target.hpp +++ b/src/trans/target.hpp @@ -17,23 +17,35 @@ 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; + ::std::string m_name = ""; + unsigned m_pointer_bits = 32; + bool m_big_endian = false; struct { - bool u8; - bool u16; - bool u32; - bool u64; - bool ptr; + bool u8 = true; + bool u16 = true; + bool u32 = true; + bool u64 = false; + bool ptr = true; } m_atomics; + + struct { + 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; + } 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; diff --git a/tools/common/toml.cpp b/tools/common/toml.cpp index 489f32b6..285d22a4 100644 --- a/tools/common/toml.cpp +++ b/tools/common/toml.cpp @@ -80,11 +80,8 @@ struct Token }; TomlFile::TomlFile(const ::std::string& filename): - m_if(filename) + m_lexer(filename) { - if( !m_if.is_open() ) { - throw ::std::runtime_error("Unable to open file '" + filename + "'"); - } } TomlFileIter TomlFile::begin() { @@ -99,12 +96,14 @@ TomlFileIter TomlFile::end() TomlKeyValue TomlFile::get_next_value() { - auto t = Token::lex_from(m_if); + auto t = m_lexer.get_token(); if(m_current_composite.empty()) { while( t.m_type == Token::Type::Newline ) - t = Token::lex_from(m_if); + { + t = m_lexer.get_token(); + } // Expect '[', a string, or an identifier switch(t.m_type) @@ -116,32 +115,32 @@ TomlKeyValue TomlFile::get_next_value() m_current_block.clear(); do { - t = Token::lex_from(m_if); + t = m_lexer.get_token(); bool is_array = false; if(t.m_type == Token::Type::SquareOpen) { is_array = true; - t = Token::lex_from(m_if); + t = m_lexer.get_token(); } assert(t.m_type == Token::Type::Ident || t.m_type == Token::Type::String); m_current_block.push_back(t.as_string()); if(is_array) { m_current_block.push_back(::format(m_array_counts[t.as_string()]++)); - t = Token::lex_from(m_if); + t = m_lexer.get_token(); assert(t.m_type == Token::Type::SquareClose); } - t = Token::lex_from(m_if); + t = m_lexer.get_token(); } while(t.m_type == Token::Type::Dot); if( t.m_type != Token::Type::SquareClose ) { - throw ::std::runtime_error(::format("Unexpected token in block header - ", t)); + throw ::std::runtime_error(::format(m_lexer, ": Unexpected token in block header - ", t)); } - t = Token::lex_from(m_if); + t = m_lexer.get_token(); if (t.m_type != Token::Type::Newline) { - throw ::std::runtime_error(::format("Unexpected token after block block - ", t)); + throw ::std::runtime_error(::format(m_lexer, ": Unexpected token after block block - ", t)); } DEBUG("Start block " << m_current_block); // Recurse! @@ -156,7 +155,7 @@ TomlKeyValue TomlFile::get_next_value() if( t.m_type == Token::Type::Eof ) { // EOF isn't allowed here - throw ::std::runtime_error(::format("Unexpected EOF in composite")); + throw ::std::runtime_error(::format(m_lexer, ": Unexpected EOF in composite")); } } switch (t.m_type) @@ -165,14 +164,14 @@ TomlKeyValue TomlFile::get_next_value() case Token::Type::Ident: break; default: - throw ::std::runtime_error(::format("Unexpected token for key - ", t)); + throw ::std::runtime_error(::format(m_lexer, ": Unexpected token for key - ", t)); } ::std::string key_name = t.as_string(); - t = Token::lex_from(m_if); + t = m_lexer.get_token(); if(t.m_type != Token::Type::Assign) - throw ::std::runtime_error(::format("Unexpected token after key - ", t)); - t = Token::lex_from(m_if); + throw ::std::runtime_error(::format(m_lexer, ": Unexpected token after key - ", t)); + t = m_lexer.get_token(); // --- Value --- TomlKeyValue rv; @@ -193,10 +192,12 @@ TomlKeyValue TomlFile::get_next_value() rv.path.push_back(key_name); rv.value.m_type = TomlValue::Type::List; - while( (t = Token::lex_from(m_if)).m_type != Token::Type::SquareClose ) + while( (t = m_lexer.get_token()).m_type != Token::Type::SquareClose ) { while( t.m_type == Token::Type::Newline ) - t = Token::lex_from(m_if); + { + t = m_lexer.get_token(); + } if( t.m_type == Token::Type::SquareClose ) break; @@ -208,15 +209,15 @@ TomlKeyValue TomlFile::get_next_value() rv.value.m_sub_values.push_back(TomlValue { t.as_string() }); break; default: - throw ::std::runtime_error(::format("Unexpected token in array value position - ", t)); + throw ::std::runtime_error(::format(m_lexer, ": Unexpected token in array value position - ", t)); } - t = Token::lex_from(m_if); + t = m_lexer.get_token(); if(t.m_type != Token::Type::Comma) break; } if(t.m_type != Token::Type::SquareClose) - throw ::std::runtime_error(::format("Unexpected token after array - ", t)); + throw ::std::runtime_error(::format(m_lexer, ": Unexpected token after array - ", t)); break; case Token::Type::BraceOpen: m_current_composite.push_back(key_name); @@ -228,7 +229,7 @@ TomlKeyValue TomlFile::get_next_value() rv.path.insert(rv.path.end(), m_current_composite.begin(), m_current_composite.end()); rv.path.push_back(key_name); rv.value = TomlValue { t.m_intval }; - return rv; + break; case Token::Type::Ident: if( t.m_data == "true" ) { @@ -247,34 +248,58 @@ TomlKeyValue TomlFile::get_next_value() } else { - throw ::std::runtime_error(::format("Unexpected identifier in value position - ", t)); + throw ::std::runtime_error(::format(m_lexer, ": Unexpected identifier in value position - ", t)); } break; default: - throw ::std::runtime_error(::format("Unexpected token in value position - ", t)); + throw ::std::runtime_error(::format(m_lexer, ": Unexpected token in value position - ", t)); } - t = Token::lex_from(m_if); + t = m_lexer.get_token(); while (!m_current_composite.empty() && t.m_type == Token::Type::BraceClose) { DEBUG("Leave composite block " << m_current_block << ", " << m_current_composite); m_current_composite.pop_back(); - t = Token::lex_from(m_if); + t = m_lexer.get_token(); } if( m_current_composite.empty() ) { // TODO: Allow EOF? if(t.m_type != Token::Type::Newline) - throw ::std::runtime_error(::format("Unexpected token in TOML file after entry - ", t)); + throw ::std::runtime_error(::format(m_lexer, ": Unexpected token in TOML file after entry - ", t)); } else { if( t.m_type != Token::Type::Comma ) - throw ::std::runtime_error(::format("Unexpected token in TOML file after composite entry - ", t)); + throw ::std::runtime_error(::format(m_lexer, ": Unexpected token in TOML file after composite entry - ", t)); } return rv; } +TomlLexer::TomlLexer(const ::std::string& filename) + :m_if(filename) + ,m_filename(filename) + ,m_line(1) +{ + if( !m_if.is_open() ) { + throw ::std::runtime_error("Unable to open file '" + filename + "'"); + } +} +Token TomlLexer::get_token() +{ + auto rv = Token::lex_from(m_if); + if( rv.m_type == Token::Type::Newline ) + { + m_line ++; + } + return rv; +} +::std::ostream& operator<<(::std::ostream& os, const TomlLexer& x) +{ + os << x.m_filename << ":" << x.m_line; + return os; +} + Token Token::lex_from(::std::ifstream& is) { auto rv = Token::lex_from_inner(is); diff --git a/tools/common/toml.h b/tools/common/toml.h index 4c97e7f2..17e05142 100644 --- a/tools/common/toml.h +++ b/tools/common/toml.h @@ -15,11 +15,28 @@ class TomlFileIter; struct TomlKeyValue; -class TomlFile +struct Token; +class TomlLexer { + friend class TomlFile; /// Input file stream ::std::ifstream m_if; + ::std::string m_filename; + unsigned m_line; +protected: + TomlLexer(const ::std::string& filename); + Token get_token(); + +public: + friend ::std::ostream& operator<<(::std::ostream& os, const TomlLexer& x); +}; + +class TomlFile +{ + /// Input file stream + TomlLexer m_lexer; + /// Name of the current `[]` block ::std::vector<::std::string> m_current_block; @@ -40,6 +57,8 @@ public: // Obtain the next value in the file TomlKeyValue get_next_value(); + + const TomlLexer& lexer() const; }; struct TomlValue -- cgit v1.2.3 From f893005e2b0a207826d56782afcd456754adb643 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 15 Dec 2018 15:40:54 +0800 Subject: Trans Target - Fix MSVC build --- src/trans/target.cpp | 12 ++++++------ src/trans/target.hpp | 42 ++++++++++++++++++++++++++++++------------ 2 files changed, 36 insertions(+), 18 deletions(-) (limited to 'src/trans/target.cpp') diff --git a/src/trans/target.cpp b/src/trans/target.cpp index 332a7e04..53d84030 100644 --- a/src/trans/target.cpp +++ b/src/trans/target.cpp @@ -17,32 +17,32 @@ const TargetArch ARCH_X86_64 = { "x86_64", 64, false, - { /*atomic(u8)=*/true, false, true, true, true }, - { 2, 4, 8, 16, 4, 8, 8 }, + 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 }, - { 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 + 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 }, - { 2, 4, 8, 16, 4, 8, 8 }, + TargetArch::Alignments(2, 4, 8, 16, 4, 8, 8) }; const TargetArch ARCH_ARM32 = { "arm", 32, false, { /*atomic(u8)=*/true, false, true, false, true }, - { 2, 4, 8, 16, 4, 8, 4 } // Note, all types are natively aligned (but i128 will be emulated) + 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 }, - { 2, 4, 8, 16, 4, 8, 4 } // TODO: Does m68k have lower alignments? + TargetArch::Alignments(2, 4, 8, 16, 4, 8, 4) // TODO: Does m68k have lower alignments? }; TargetSpec g_target; diff --git a/src/trans/target.hpp b/src/trans/target.hpp index b6f04a42..4e0309dd 100644 --- a/src/trans/target.hpp +++ b/src/trans/target.hpp @@ -20,26 +20,44 @@ enum class CodegenMode // 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 = 32; - bool m_big_endian = false; + ::std::string m_name; + unsigned m_pointer_bits; + bool m_big_endian; - struct { + 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 { - 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; + 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 -- cgit v1.2.3 From 17f910e871e70a5edbf32ea05ef8f68bc71003c9 Mon Sep 17 00:00:00 2001 From: John Paul Adrian Glaubitz Date: Sat, 22 Dec 2018 15:49:16 +0100 Subject: Trans - Fix alignment values for m68k --- src/trans/target.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/trans/target.cpp') diff --git a/src/trans/target.cpp b/src/trans/target.cpp index 53d84030..316749be 100644 --- a/src/trans/target.cpp +++ b/src/trans/target.cpp @@ -42,7 +42,7 @@ const TargetArch ARCH_M68K = { "m68k", 32, true, { /*atomic(u8)=*/true, false, true, false, true }, - TargetArch::Alignments(2, 4, 8, 16, 4, 8, 4) // TODO: Does m68k have lower alignments? + TargetArch::Alignments(2, 2, 2, 2, 2, 2, 2) }; TargetSpec g_target; -- cgit v1.2.3 From cbed0d2930168ef15bfdeb02c6f12991094b1480 Mon Sep 17 00:00:00 2001 From: Alexander von Gluck IV Date: Mon, 21 Jan 2019 23:30:06 +0000 Subject: targets: Add x86_64 and arm targets for Haiku --- src/trans/target.cpp | 14 ++++++++++++++ tools/common/target_detect.h | 9 +++++++++ 2 files changed, 23 insertions(+) (limited to 'src/trans/target.cpp') diff --git a/src/trans/target.cpp b/src/trans/target.cpp index 316749be..70996fb0 100644 --- a/src/trans/target.cpp +++ b/src/trans/target.cpp @@ -511,6 +511,20 @@ namespace 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 + }; + } else { ::std::cerr << "Unknown target name '" << target_name << "'" << ::std::endl; diff --git a/tools/common/target_detect.h b/tools/common/target_detect.h index 0812c363..1bfc7dd9 100644 --- a/tools/common/target_detect.h +++ b/tools/common/target_detect.h @@ -75,6 +75,15 @@ // - Apple devices #elif defined(__APPLE__) # define DEFAULT_TARGET_NAME "x86_64-apple-macosx" +// - Haiku +#elif defined(__HAIKU__) +# if defined(__x86_64__) +# define DEFAULT_TARGET_NAME "x86_64-unknown-haiku" +# elif defined(__arm__) +# define DEFAULT_TARGET_NAME "arm-unknown-haiku" +# else +# warning "Unable to detect a suitable default target (Haiku)" +# endif // - Unknown #else # warning "Unable to detect a suitable default target" -- cgit v1.2.3