aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2016-05-06 23:10:14 -0700
committerAndrew Kelley <superjoe30@gmail.com>2016-05-06 23:10:14 -0700
commitc098a8f5223855b410895b5396948e3e2b3aacba (patch)
treeac3c4e5fa9de71a1b703d52433e0e1cec3abe7cf /src/codegen.cpp
parent271a37b418828c8ee79402f97016be42c5fa2884 (diff)
downloadzig-c098a8f5223855b410895b5396948e3e2b3aacba.tar.gz
zig-c098a8f5223855b410895b5396948e3e2b3aacba.zip
add frame_address and return_address builtins
Diffstat (limited to 'src/codegen.cpp')
-rw-r--r--src/codegen.cpp27
1 files changed, 27 insertions, 0 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp
index 9e2f2bc91f..8ecdd36358 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -634,6 +634,13 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) {
case BuiltinFnIdBreakpoint:
set_debug_source_node(g, node);
return LLVMBuildCall(g->builder, g->trap_fn_val, nullptr, 0, "");
+ case BuiltinFnIdFrameAddress:
+ case BuiltinFnIdReturnAddress:
+ {
+ LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_i32->type_ref);
+ set_debug_source_node(g, node);
+ return LLVMBuildCall(g->builder, builtin_fn->fn_val, &zero, 1, "");
+ }
case BuiltinFnIdCmpExchange:
return gen_cmp_exchange(g, node);
case BuiltinFnIdFence:
@@ -4331,6 +4338,26 @@ static void define_builtin_fns(CodeGen *g) {
g->trap_fn_val = builtin_fn->fn_val;
}
{
+ BuiltinFnEntry *builtin_fn = create_builtin_fn_with_arg_count(g, BuiltinFnIdReturnAddress,
+ "return_address", 0);
+ builtin_fn->return_type = get_pointer_to_type(g, g->builtin_types.entry_u8, true);
+
+ LLVMTypeRef fn_type = LLVMFunctionType(builtin_fn->return_type->type_ref,
+ &g->builtin_types.entry_i32->type_ref, 1, false);
+ builtin_fn->fn_val = LLVMAddFunction(g->module, "llvm.returnaddress", fn_type);
+ assert(LLVMGetIntrinsicID(builtin_fn->fn_val));
+ }
+ {
+ BuiltinFnEntry *builtin_fn = create_builtin_fn_with_arg_count(g, BuiltinFnIdFrameAddress,
+ "frame_address", 0);
+ builtin_fn->return_type = get_pointer_to_type(g, g->builtin_types.entry_u8, true);
+
+ LLVMTypeRef fn_type = LLVMFunctionType(builtin_fn->return_type->type_ref,
+ &g->builtin_types.entry_i32->type_ref, 1, false);
+ builtin_fn->fn_val = LLVMAddFunction(g->module, "llvm.frameaddress", fn_type);
+ assert(LLVMGetIntrinsicID(builtin_fn->fn_val));
+ }
+ {
BuiltinFnEntry *builtin_fn = create_builtin_fn(g, BuiltinFnIdMemcpy, "memcpy");
builtin_fn->return_type = g->builtin_types.entry_void;
builtin_fn->param_count = 3;