summaryrefslogtreecommitdiff
path: root/src/trans/codegen_c.cpp
diff options
context:
space:
mode:
authorJohn Hodge (bugs) <tpg@mutabah.net>2017-07-07 17:25:29 +0800
committerJohn Hodge (bugs) <tpg@mutabah.net>2017-07-07 17:25:29 +0800
commit029dd3f14422f0587b63e33781afe072bafc094a (patch)
tree37155bc2240f8b82210a03e8c08ad62122010885 /src/trans/codegen_c.cpp
parent23aee59a64e9febf4c1faab27b8fb341a2b2271c (diff)
downloadmrust-029dd3f14422f0587b63e33781afe072bafc094a.tar.gz
Codegen C - Rough support for MSVC compatible code
Diffstat (limited to 'src/trans/codegen_c.cpp')
-rw-r--r--src/trans/codegen_c.cpp147
1 files changed, 107 insertions, 40 deletions
diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp
index aa0d6cb8..24930378 100644
--- a/src/trans/codegen_c.cpp
+++ b/src/trans/codegen_c.cpp
@@ -133,21 +133,48 @@ namespace {
<< "#include <string.h>\n" // mem*
<< "#include <math.h>\n" // round, ...
;
+ switch(m_compiler)
+ {
+ case Compiler::Gcc:
+ m_of
+ << "#include <stdatomic.h>\n" // atomic_*
+ ;
+ break;
+ case Compiler::Msvc:
+ m_of
+ << "#include <Windows.h>\n" // Interlocked*
+ ;
+ break;
+ }
m_of
- << "#include <stdatomic.h>\n" // atomic_*
- ;
- m_of
- << "typedef uint32_t CHAR;\n"
- << "typedef struct { } tUNIT;\n"
- << "typedef struct { } tBANG;\n"
- << "typedef struct { } tTYPEID;\n"
+ << "typedef uint32_t RUST_CHAR;\n"
+ << "typedef struct { char _d; } tUNIT;\n"
+ << "typedef struct { char _d; } tBANG;\n"
+ << "typedef struct { char _d; } tTYPEID;\n"
<< "typedef struct { void* PTR; size_t META; } SLICE_PTR;\n"
<< "typedef struct { void* PTR; void* META; } TRAITOBJ_PTR;\n"
<< "typedef struct { size_t size; size_t align; void (*drop)(void*); } VTABLE_HDR;\n"
- << "typedef unsigned __int128 uint128_t;\n"
- << "typedef signed __int128 int128_t;\n"
<< "\n"
- << "extern void _Unwind_Resume(void) __attribute__((noreturn));\n"
+ ;
+ switch(m_compiler)
+ {
+ case Compiler::Gcc:
+ m_of
+ << "typedef unsigned __int128 uint128_t;\n"
+ << "typedef signed __int128 int128_t;\n"
+ << "extern void _Unwind_Resume(void) __attribute__((noreturn));\n"
+ ;
+ case Compiler::Msvc:
+ m_of << "__declspec(noreturn) extern void _Unwind_Resume(void);\n";
+ //case Compilter::Std11:
+ m_of
+ << "typedef unsigned _int128 uint128_t;\n"
+ << "typedef signed _int128 int128_t;\n"
+ ;
+ break;
+ }
+ // Common helpers
+ m_of
<< "\n"
<< "static inline int slice_cmp(SLICE_PTR l, SLICE_PTR r) {\n"
<< "\tint rv = memcmp(l.PTR, r.PTR, l.META < r.META ? l.META : r.META);\n"
@@ -163,30 +190,36 @@ namespace {
<< "static inline void noop_drop(void *p) {}\n"
<< "\n"
;
- // 64-bit bit ops
- 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"
- << "}\n"
- << "static inline uint64_t __builtin_ctz64(uint64_t v) {\n"
- << "\treturn ((v&0xFFFFFFFF) == 0 ? __builtin_ctz(v>>32) + 32 : __builtin_ctz(v));\n"
- << "}\n"
- ;
- // u128/i128 ops
- m_of
- << "static inline unsigned __int128 __builtin_bswap128(uint128_t v) {\n"
- << "\tuint64_t lo = __builtin_bswap64((uint64_t)v);\n"
- << "\tuint64_t hi = __builtin_bswap64((uint64_t)(v>>64));\n"
- << "\treturn ((uint128_t)lo << 64) | (uint128_t)hi;\n"
- << "}\n"
- << "static inline uint128_t __builtin_clz128(uint128_t v) {\n"
- << "\treturn (v >> 64 != 0 ? __builtin_clz64(v>>64) : 64 + __builtin_clz64(v));\n"
- << "}\n"
- << "static inline uint128_t __builtin_ctz128(uint128_t v) {\n"
- << "\treturn ((v&0xFFFFFFFFFFFFFFFF) == 0 ? __builtin_ctz64(v>>64) + 64 : __builtin_ctz64(v));\n"
- << "}\n"
- << "\n"
- ;
+ switch (m_compiler)
+ {
+ case Compiler::Gcc:
+ // 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"
+ << "}\n"
+ << "static inline uint64_t __builtin_ctz64(uint64_t v) {\n"
+ << "\treturn ((v&0xFFFFFFFF) == 0 ? __builtin_ctz(v>>32) + 32 : __builtin_ctz(v));\n"
+ << "}\n"
+ ;
+ // u128/i128 ops (gcc intrinsics)
+ m_of
+ << "static inline unsigned __int128 __builtin_bswap128(uint128_t v) {\n"
+ << "\tuint64_t lo = __builtin_bswap64((uint64_t)v);\n"
+ << "\tuint64_t hi = __builtin_bswap64((uint64_t)(v>>64));\n"
+ << "\treturn ((uint128_t)lo << 64) | (uint128_t)hi;\n"
+ << "}\n"
+ << "static inline uint128_t __builtin_clz128(uint128_t v) {\n"
+ << "\treturn (v >> 64 != 0 ? __builtin_clz64(v>>64) : 64 + __builtin_clz64(v));\n"
+ << "}\n"
+ << "static inline uint128_t __builtin_ctz128(uint128_t v) {\n"
+ << "\treturn ((v&0xFFFFFFFFFFFFFFFF) == 0 ? __builtin_ctz64(v>>64) + 64 : __builtin_ctz64(v));\n"
+ << "}\n"
+ << "\n"
+ ;
+ case Compiler::Msvc:
+ break;
+ }
}
~CodeGenerator_C() {}
@@ -550,8 +583,11 @@ namespace {
TU_MATCHA( (item.m_data), (e),
(Unit,
+ m_of << "\tchar _d;\n";
),
(Tuple,
+ if( e.empty() )
+ m_of << "\tchar _d;\n";
for(unsigned int i = 0; i < e.size(); i ++)
{
const auto& fld = e[i];
@@ -561,6 +597,8 @@ namespace {
}
),
(Named,
+ if (e.empty())
+ m_of << "\tchar _d;\n";
for(unsigned int i = 0; i < e.size(); i ++)
{
const auto& fld = e[i].second;
@@ -791,10 +829,10 @@ namespace {
{
TU_MATCHA( (item.m_variants[i].second), (e),
(Unit,
- m_of << "\t\tstruct {} var_" << i << ";\n";
+ //m_of << "\t\tstruct {} var_" << i << ";\n";
),
(Value,
- m_of << "\t\tstruct {} var_" << i << ";\n";
+ //m_of << "\t\tstruct {} var_" << i << ";\n";
),
(Tuple,
m_of << "\t\tstruct {\n";
@@ -1365,7 +1403,15 @@ namespace {
// Size, Alignment, and destructor
m_of << "\t{ ";
m_of << "sizeof("; emit_ctype(type); m_of << "),";
- m_of << "__alignof__("; emit_ctype(type); m_of << "),";
+ switch(m_compiler)
+ {
+ case Compiler::Gcc:
+ m_of << "__alignof__("; emit_ctype(type); m_of << "),";
+ break;
+ case Compiler::Msvc:
+ m_of << "__alignof("; emit_ctype(type); m_of << "),";
+ break;
+ }
if( type.m_data.is_Borrow() || m_resolve.type_is_copy(sp, type) )
{
m_of << "noop_drop,";
@@ -1851,13 +1897,34 @@ namespace {
return ;
}
+ ::HIR::TypeRef tmp;
+ const auto& ty = mir_res.get_lvalue_type(tmp, ve.val);
+
+ // A cast to a fat pointer doesn't actually change the C type.
+ if( (ve.type.m_data.is_Pointer() && is_dst(*ve.type.m_data.as_Pointer().inner))
+ || (ve.type.m_data.is_Borrow() && is_dst(*ve.type.m_data.as_Borrow().inner))
+ // OR: If it's a no-op cast
+ || ve.type == ty
+ )
+ {
+ emit_lvalue(e.dst);
+ m_of << " = ";
+ emit_lvalue(ve.val);
+ break;
+ }
+ //if( m_emulated_i128 && (
+ // ve.type == ::HIR::CoreType::U128 || ve.type == ::HIR::CoreType::I128
+ // || ty == ::HIR::CoreType::U128 || ty == ::HIR::CoreType::I128
+ // ) )
+ //{
+ // if( ty == ::HIR::CoreType::U128
+ //}
+
emit_lvalue(e.dst);
m_of << " = ";
m_of << "("; emit_ctype(ve.type); m_of << ")";
// TODO: If the source is an unsized borrow, then extract the pointer
bool special = false;
- ::HIR::TypeRef tmp;
- const auto& ty = mir_res.get_lvalue_type(tmp, ve.val);
// If the destination is a thin pointer
if( ve.type.m_data.is_Pointer() && !is_dst( *ve.type.m_data.as_Pointer().inner ) )
{
@@ -3404,7 +3471,7 @@ namespace {
case ::HIR::CoreType::F64: m_of << "double"; break;
case ::HIR::CoreType::Bool: m_of << "bool"; break;
- case ::HIR::CoreType::Char: m_of << "CHAR"; break;
+ case ::HIR::CoreType::Char: m_of << "RUST_CHAR"; break;
case ::HIR::CoreType::Str:
MIR_BUG(*m_mir_res, "Raw str");
}