diff options
author | John Hodge <tpg@mutabah.net> | 2016-12-11 12:34:00 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-12-11 12:34:00 +0800 |
commit | a32d452ee6792663a1d73d4b082c224a20c3caa4 (patch) | |
tree | f648da493d8b7677e9fa0eb3f423df151176525a /src/trans/codegen_c.cpp | |
parent | 5f22f9f6d48411d56d9999d9a7d2c64b1aa31e73 (diff) | |
download | mrust-a32d452ee6792663a1d73d4b082c224a20c3caa4.tar.gz |
Trans C - A few extra intrinsics, fix atomic cxchg
Diffstat (limited to 'src/trans/codegen_c.cpp')
-rw-r--r-- | src/trans/codegen_c.cpp | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp index a8fe0b0b..6bac1e09 100644 --- a/src/trans/codegen_c.cpp +++ b/src/trans/codegen_c.cpp @@ -41,7 +41,9 @@ namespace { << "#include <stddef.h>\n" << "#include <stdint.h>\n" << "#include <stdbool.h>\n" - << "#include <string.h>\n" + << "#include <stdatomic.h>\n" // atomic_* + << "#include <stdlib.h>\n" // abort + << "#include <string.h>\n" // mem* << "typedef uint32_t CHAR;\n" << "typedef struct { } tUNIT;\n" << "typedef struct { } tBANG;\n" @@ -634,9 +636,10 @@ namespace { } }; auto emit_atomic_cxchg = [&](const auto& e, const char* o_succ, const char* o_fail) { - emit_lvalue(e.ret_val); m_of << " = atomic_compare_exchange_strong_explicit("; + emit_lvalue(e.ret_val); m_of << "._0 = "; emit_lvalue(e.args.at(1)); m_of << ";\n\t"; + emit_lvalue(e.ret_val); m_of << "._1 = atomic_compare_exchange_strong_explicit("; emit_lvalue(e.args.at(0)); - m_of << ", &"; emit_lvalue(e.args.at(1)); + m_of << ", &"; emit_lvalue(e.ret_val); m_of << "._0"; m_of << ", "; emit_lvalue(e.args.at(2)); m_of << ", "<<o_succ<<", "<<o_fail<<")"; }; @@ -668,6 +671,23 @@ namespace { else if( name == "abort" ) { m_of << "abort()"; } + else if( name == "offset" ) { + emit_lvalue(e.ret_val); m_of << " = "; emit_lvalue(e.args.at(0)); m_of << " + "; emit_lvalue(e.args.at(1)); + } + else if( name == "arith_offset" ) { + emit_lvalue(e.ret_val); m_of << " = "; emit_lvalue(e.args.at(0)); m_of << " + "; emit_lvalue(e.args.at(1)); + } + // Hints + else if( name == "unreachable" ) { + m_of << "__builtin_unreachable()"; + } + else if( name == "assume" ) { + // I don't assume :) + } + else if( name == "likely" ) { + } + else if( name == "unlikely" ) { + } // Overflowing Arithmatic // HACK: Uses GCC intrinsics else if( name == "add_with_overflow" ) { @@ -700,6 +720,10 @@ namespace { m_of << ", "; emit_lvalue(e.args.at(1)); m_of << ", &"; emit_lvalue(e.ret_val); m_of << ")"; } + // Bit Twiddling + else if( name == "ctlz" ) { + emit_lvalue(e.ret_val); m_of << " = __builtin_clz("; emit_lvalue(e.args.at(0)); m_of << ")"; + } // --- Atomics! // > Single-ordering atomics else if( name == "atomic_xadd" || name.compare(0, 7+4+1, "atomic_xadd_") == 0 ) { |