Skip to content

Commit

Permalink
Codegen C - Pile of hackery, libcore 1.74 builds!
Browse files Browse the repository at this point in the history
  • Loading branch information
thepowersgang committed Jan 16, 2024
1 parent 1452f17 commit 2264343
Showing 1 changed file with 122 additions and 13 deletions.
135 changes: 122 additions & 13 deletions src/trans/codegen_c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "target.hpp"
#include "allocator.hpp"
#include <iomanip>
#include "target_version.hpp"

namespace {
struct FmtShell
Expand Down Expand Up @@ -700,6 +701,8 @@ namespace {
<< "static inline int128_t xor128s(int128_t a, int128_t b) { int128_t v = { a.lo ^ b.lo, a.hi ^ b.hi }; return v; }\n"
<< "static inline int128_t shl128s(int128_t a, uint32_t b) { int128_t v; if(b == 0) { return a; } else if(b < 64) { v.lo = a.lo << b; v.hi = (a.hi << b) | (a.lo >> (64 - b)); } else { v.hi = a.lo << (b - 64); v.lo = 0; } return v; }\n"
<< "static inline int128_t shr128s(int128_t a, uint32_t b) { int128_t v; if(b == 0) { return a; } else if(b < 64) { v.lo = (a.lo >> b)|(a.hi << (64 - b)); v.hi = (int64_t)a.hi >> b; } else { v.lo = (int64_t)a.hi >> (b - 64); v.hi = (int64_t)a.hi < 0 ? -1 : 0; } return v; }\n"
<< "static inline uint128_t int128_to_uint128(int128_t a) { return make128_raw(a.lo, a.hi); }\n"
<< "static inline int128_t uint128_to_int128(uint128_t a) { return make128s_raw(a.lo, a.hi); }\n"
;
}
else
Expand Down Expand Up @@ -2554,8 +2557,8 @@ namespace {
}
// `fn llvm_addcarryx_u32(a: u8, b: u32, c: u32, d: *mut u8) -> u8`
else if( item.m_linkage.name == "llvm.x86.addcarryx.u32") {
m_of << "\trv = __builtin_add_overflow" << msvc_suffix_u32 << "(arg1, arg2, arg3);\n";
m_of << "\tif(arg0) rv |= __builtin_add_overflow" << msvc_suffix_u32 << "(*arg3, 1, arg3);\n";
m_of << "\trv = __builtin_add_overflow" << msvc_suffix_u32 << "(arg1, arg2, (uint32_t*)arg3);\n";
m_of << "\tif(arg0) rv |= __builtin_add_overflow" << msvc_suffix_u32 << "(*arg3, 1, (uint32_t*)arg3);\n";
m_of << "\treturn rv;\n";
}
// `fn llvm_subborrow" << msvc_suffix_u32 << "(a: u8, b: u32, c: u32) -> (u8, u32);`
Expand Down Expand Up @@ -2689,6 +2692,7 @@ namespace {
m_of << "\n";
m_of << "{\n";

#if 1
if( m_compiler == Compiler::Msvc && p.m_data.is_Generic() )
{
const auto& gp = p.m_data.as_Generic();
Expand All @@ -2702,18 +2706,82 @@ namespace {
|| gp.m_path.m_components.back().compare(0, 4, "_mm_") == 0
)
{
m_of << "\treturn " << gp.m_path.m_components.back() << "(";
// HACK: These aren't supported on msvc2019
if( true
|| gp.m_path.m_components.back() == "_mm256_zextpd128_pd256"
) {
m_of << "\tabort();";
m_of << "}\n";
return ;
}
struct H {
static const char* get_intr_type(const HIR::TypeRef& ty) {
if( ty.data().is_Path() ) {
const auto& p = ty.data().as_Path().path.m_data.as_Generic();
if( false
|| p.m_path.m_components.back() == "__m128"
|| p.m_path.m_components.back() == "__m128d"
|| p.m_path.m_components.back() == "__m128i"
|| p.m_path.m_components.back() == "__m256"
|| p.m_path.m_components.back() == "__m256d"
|| p.m_path.m_components.back() == "__m256i"
) {
return p.m_path.m_components.back().c_str();
}
}
return nullptr;
}
};
const char* rv_type = nullptr;
if( ret_type.data().is_Tuple() && ret_type.data().as_Tuple().empty() ) {
rv_type = "";
}
else {
rv_type = H::get_intr_type(ret_type);
}

if(!rv_type) {
m_of << "\t";
emit_ctype(ret_type, FMT_CB(ss, ss << "rv";));
m_of << ";\n";
}
else if( !rv_type[0] ) {
// Void return
}
else {
m_of << "\t" << rv_type << " rv;\n";
}
if(!rv_type || rv_type[0]) {
m_of << "\trv = ";
}
m_of << gp.m_path.m_components.back() << "(";
for(size_t i = 0; i < item.m_args.size(); i ++) {
if( i != 0 )
m_of << ", ";
if( const char* t = H::get_intr_type(item.m_args[i].second) ) {
m_of << "*(const " << t << "*)&";
}
emit_lvalue(::MIR::LValue::new_Argument(i));
}
if( ! gp.m_params.m_values.empty() ) {
m_of << ", " << EncodedLiteralSlice(*gp.m_params.m_values[0].as_Evaluated()).read_uint();
}
m_of << ");\n";
if( !rv_type || rv_type[0] ) {
m_of << "\treturn ";
if( rv_type ) {
m_of << "*(";
emit_ctype(ret_type);
m_of << "*)&";
}
m_of << "rv;\n";
}
m_of << "}\n";
return;
}
}
}
#endif

// Variables
m_of << "\t"; emit_ctype(ret_type, FMT_CB(ss, ss << "rv";)); m_of << ";\n";
Expand Down Expand Up @@ -5581,7 +5649,14 @@ namespace {
else if( name == "type_id" ) {
const auto& ty = params.m_types.at(0);
// NOTE: Would define the typeid here, but it has to be public
emit_lvalue(e.ret_val); m_of << " = (uintptr_t)&__typeid_" << Trans_Mangle(ty);
emit_lvalue(e.ret_val); m_of << " = ";
if( TARGETVER_LEAST_1_74 && m_options.emulated_i128 ) {
m_of << "make128(";
}
m_of << "(uintptr_t)&__typeid_" << Trans_Mangle(ty);
if( TARGETVER_LEAST_1_74 && m_options.emulated_i128 ) {
m_of << ")";
}
}
else if( name == "type_name" ) {
auto s = FMT(params.m_types.at(0));
Expand Down Expand Up @@ -5693,13 +5768,13 @@ namespace {
else if( name == "raw_eq" ) {
// Raw byte equality (could be implemented without a memcmp call, if desired)
size_t size = 0;
emit_lvalue(e.ret_val); m_of << " = 0 == memcmp(";
emit_lvalue(e.ret_val); m_of << " = (0 == memcmp(";
emit_param(e.args.at(0));
m_of << ", ";
emit_param(e.args.at(1));
m_of << ", ";
m_of << "sizeof("; emit_ctype(params.m_types.at(0));
m_of << ")";
m_of << "sizeof("; emit_ctype(params.m_types.at(0)); m_of << ")";
m_of << "))";
}
else if( name == "forget" ) {
// Nothing needs to be done, this just stops the destructor from running.
Expand Down Expand Up @@ -5779,7 +5854,15 @@ namespace {
// --- #[track_caller]
else if( name == "caller_location" ) {
//m_of << "abort()";
m_of << "static struct s_ZRG2cE9core0_0_05panic8Location0g mrustc_empty_caller_location = {0,0,{\"\",0}};";
auto p = m_crate.get_lang_item_path_opt("panic_location");
m_of << "static struct ";
if( p == HIR::SimplePath() ) {
m_of << "s_ZRG2cE9core0_0_05panic8Location0g";
}
else {
m_of << "s_" << Trans_Mangle(p);
}
m_of << " mrustc_empty_caller_location = {0,0,{\"\",0}};";
emit_lvalue(e.ret_val); m_of << " = &mrustc_empty_caller_location"; // TODO: Hidden ABI for caller location
}
// --- Pointer manipulation
Expand Down Expand Up @@ -6432,13 +6515,34 @@ namespace {
auto emit_arg0 = [&](){ emit_param(e.args.at(0)); };
const auto& ty = params.m_types.at(0);
emit_lvalue(e.ret_val); m_of << " = (";
if( ty == ::HIR::CoreType::U128 )
if( ty == ::HIR::CoreType::U128 || ty == ::HIR::CoreType::I128 )
{
if( ty == ::HIR::CoreType::I128 ) {
if( m_options.emulated_i128 ) {
m_of << "uint128_to_int128(";
}
else {
m_of << "(int128_t)";
}
}
if( name == "ctlz" || name == "ctlz_nonzero" ) {
m_of << "intrinsic_ctlz_u128("; emit_param(e.args.at(0)); m_of << ")";
m_of << "intrinsic_ctlz_u128(";
}
else {
m_of << "intrinsic_cttz_u128("; emit_param(e.args.at(0)); m_of << ")";
m_of << "intrinsic_cttz_u128(";
}
if( ty == ::HIR::CoreType::I128 ) {
if( m_options.emulated_i128 ) {
m_of << "int128_to_uint128(";
}
else {
m_of << "(uint128_t)";
}
}
emit_param(e.args.at(0)); m_of << ")";
if( ty == ::HIR::CoreType::I128 && m_options.emulated_i128 ) {
m_of << ")";
m_of << ")";
}
m_of << ");";
return ;
Expand Down Expand Up @@ -6754,8 +6858,13 @@ namespace {
const auto* ty_repr = Target_GetTypeRepr(self.sp, self.m_mir_res->m_resolve, ty);
MIR_ASSERT(*self.m_mir_res, ty_repr, "No repr for " << ty);
size_t size_slot = ty_repr->size;
const auto& ty_val = ty_repr->fields[0].ty.data().as_Array().inner;
DEBUG(ty_val);
const auto& ity = ty_repr->fields[0].ty;
DEBUG("SimdInfo Type: " << ity);
const auto& ty_val = ity.data().is_Primitive()
? ity
: ty_repr->fields[0].ty.data().as_Array().inner
;
DEBUG("ty_val = " << ty_val);
size_t size_val = 0;
MIR_ASSERT(*self.m_mir_res, Target_GetSizeOf(self.sp, self.m_resolve, ty_val, size_val), ty_val);

Expand Down

0 comments on commit 2264343

Please sign in to comment.