Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 93 additions & 1 deletion gcc/rust/backend/rust-builtins.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ BuiltinsContext &
BuiltinsContext::get ()
{
static BuiltinsContext instance;

if (instance.setup_state == SetupState::UNINITIALIZED)
instance.setup ();

return instance;
}

Expand All @@ -44,7 +48,26 @@ BuiltinsContext::lookup_simple_builtin (const std::string &name, tree *builtin)
return lookup_gcc_builtin (*to_search, builtin);
}

BuiltinsContext::BuiltinsContext () { setup (); }
LlvmBuiltinMappingResult
BuiltinsContext::map_llvm_to_gcc_builtin (const std::string &name,
tree *resolved,
LlvmBuiltinAdapter *adapter)
{
rust_assert (resolved != nullptr);

auto mapping = llvm_to_gcc_builtin.find (name);
if (mapping == llvm_to_gcc_builtin.end ())
return LlvmBuiltinMappingResult::NOT_MAPPED;

*resolved = NULL_TREE;
if (!lookup_gcc_builtin (mapping->second.gcc_name, resolved))
return LlvmBuiltinMappingResult::TARGET_UNAVAILABLE;

*adapter = mapping->second.adapter;
return LlvmBuiltinMappingResult::RESOLVED;
}

BuiltinsContext::BuiltinsContext () : setup_state (SetupState::UNINITIALIZED) {}

/**
* Define a function type according to `builtin-types.def`
Expand Down Expand Up @@ -355,14 +378,83 @@ BuiltinsContext::register_rust_mappings ()
};
}

void
BuiltinsContext::register_llvm_to_gcc_builtin ()
{
llvm_to_gcc_builtin = {
{"llvm.x86.rdrand.16",
{"__builtin_ia32_rdrand16_step",
LlvmBuiltinAdapter::OUTPUT_POINTER_VALUE_STATUS}},
{"llvm.x86.rdrand.32",
{"__builtin_ia32_rdrand32_step",
LlvmBuiltinAdapter::OUTPUT_POINTER_VALUE_STATUS}},
{"llvm.x86.rdrand.64",
{"__builtin_ia32_rdrand64_step",
LlvmBuiltinAdapter::OUTPUT_POINTER_VALUE_STATUS}},
{"llvm.x86.rdseed.16",
{"__builtin_ia32_rdseed_hi_step",
LlvmBuiltinAdapter::OUTPUT_POINTER_VALUE_STATUS}},
{"llvm.x86.rdseed.32",
{"__builtin_ia32_rdseed_si_step",
LlvmBuiltinAdapter::OUTPUT_POINTER_VALUE_STATUS}},
{"llvm.x86.rdseed.64",
{"__builtin_ia32_rdseed_di_step",
LlvmBuiltinAdapter::OUTPUT_POINTER_VALUE_STATUS}},

{"llvm.x86.addcarry.32",
{"__builtin_ia32_addcarryx_u32",
LlvmBuiltinAdapter::OUTPUT_POINTER_STATUS_VALUE}},
{"llvm.x86.addcarryx.u32",
{"__builtin_ia32_addcarryx_u32", LlvmBuiltinAdapter::FORWARD_ARGUMENTS}},
{"llvm.x86.subborrow.32",
{"__builtin_ia32_sbb_u32",
LlvmBuiltinAdapter::OUTPUT_POINTER_STATUS_VALUE}},
{"llvm.x86.addcarry.64",
{"__builtin_ia32_addcarryx_u64",
LlvmBuiltinAdapter::OUTPUT_POINTER_STATUS_VALUE}},
{"llvm.x86.addcarryx.u64",
{"__builtin_ia32_addcarryx_u64", LlvmBuiltinAdapter::FORWARD_ARGUMENTS}},
{"llvm.x86.subborrow.64",
{"__builtin_ia32_sbb_u64",
LlvmBuiltinAdapter::OUTPUT_POINTER_STATUS_VALUE}},

{"llvm.x86.vcvtph2ps.128",
{"__builtin_ia32_vcvtph2ps", LlvmBuiltinAdapter::FORWARD_ARGUMENTS}},
{"llvm.x86.vcvtph2ps.256",
{"__builtin_ia32_vcvtph2ps256", LlvmBuiltinAdapter::FORWARD_ARGUMENTS}},
{"llvm.x86.vcvtps2ph.128",
{"__builtin_ia32_vcvtps2ph", LlvmBuiltinAdapter::FORWARD_ARGUMENTS}},
{"llvm.x86.vcvtps2ph.256",
{"__builtin_ia32_vcvtps2ph256", LlvmBuiltinAdapter::FORWARD_ARGUMENTS}},
};
}

void
BuiltinsContext::register_builtin (tree decl)
{
rust_assert (TREE_CODE (decl) == FUNCTION_DECL);
rust_assert (DECL_NAME (decl));

const char *name = IDENTIFIER_POINTER (DECL_NAME (decl));
builtin_functions.insert ({std::string (name), decl});
}

void
BuiltinsContext::setup ()
{
rust_assert (setup_state == SetupState::UNINITIALIZED);
setup_state = SetupState::INITIALIZING;

define_builtin_types ();
define_builtin_attributes ();
define_builtins ();

targetm.init_builtins ();

register_rust_mappings ();
register_llvm_to_gcc_builtin ();

setup_state = SetupState::READY;
}

bool
Expand Down
37 changes: 37 additions & 0 deletions gcc/rust/backend/rust-builtins.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,39 @@ namespace Compile {
// };
// Some(cx.get_intrinsic(&llvm_name))

enum class LlvmBuiltinMappingResult
{
NOT_MAPPED,
TARGET_UNAVAILABLE,
RESOLVED,
};

enum class LlvmBuiltinAdapter
{
OUTPUT_POINTER_VALUE_STATUS,
OUTPUT_POINTER_STATUS_VALUE,
FORWARD_ARGUMENTS,
};

struct LlvmBuiltinMapping
{
std::string gcc_name;
LlvmBuiltinAdapter adapter;
};

class BuiltinsContext
{
public:
static BuiltinsContext &get ();

bool lookup_simple_builtin (const std::string &name, tree *builtin);

LlvmBuiltinMappingResult
map_llvm_to_gcc_builtin (const std::string &name, tree *resolved,
LlvmBuiltinAdapter *adapter);

void register_builtin (tree decl);

private:
enum Type
{
Expand Down Expand Up @@ -166,6 +192,15 @@ class BuiltinsContext
ATTR_LAST,
};

enum class SetupState
{
UNINITIALIZED,
INITIALIZING,
READY,
};

SetupState setup_state;

/**
* All builtin types, as defined in `builtin-types.def`
*
Expand All @@ -190,6 +225,7 @@ class BuiltinsContext
void define_builtins ();

void register_rust_mappings ();
void register_llvm_to_gcc_builtin ();

BuiltinsContext ();

Expand All @@ -204,6 +240,7 @@ class BuiltinsContext
// A mapping of the GCC built-ins exposed to GCC Rust.
std::map<std::string, tree> builtin_functions;
std::map<std::string, std::string> rust_intrinsic_to_gcc_builtin;
std::map<std::string, LlvmBuiltinMapping> llvm_to_gcc_builtin;
};

} // namespace Compile
Expand Down
Loading
Loading