aboutsummaryrefslogtreecommitdiff
path: root/gcc/builtins.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r--gcc/builtins.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c
index e6b10ea..fb8d83a 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -5744,6 +5744,45 @@ expand_builtin_sync_synchronize (void)
expand_mem_thread_fence (MEMMODEL_SEQ_CST);
}
+static rtx
+expand_builtin_thread_pointer (tree exp, rtx target)
+{
+ enum insn_code icode;
+ if (!validate_arglist (exp, VOID_TYPE))
+ return const0_rtx;
+ icode = direct_optab_handler (get_thread_pointer_optab, Pmode);
+ if (icode != CODE_FOR_nothing)
+ {
+ struct expand_operand op;
+ if (!REG_P (target) || GET_MODE (target) != Pmode)
+ target = gen_reg_rtx (Pmode);
+ create_output_operand (&op, target, Pmode);
+ expand_insn (icode, 1, &op);
+ return target;
+ }
+ error ("__builtin_thread_pointer is not supported on this target");
+ return const0_rtx;
+}
+
+static void
+expand_builtin_set_thread_pointer (tree exp)
+{
+ enum insn_code icode;
+ if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
+ return;
+ icode = direct_optab_handler (set_thread_pointer_optab, Pmode);
+ if (icode != CODE_FOR_nothing)
+ {
+ struct expand_operand op;
+ rtx val = expand_expr (CALL_EXPR_ARG (exp, 0), NULL_RTX,
+ Pmode, EXPAND_NORMAL);
+ create_fixed_operand (&op, val);
+ expand_insn (icode, 1, &op);
+ return;
+ }
+ error ("__builtin_set_thread_pointer is not supported on this target");
+}
+
/* Expand an expression EXP that calls a built-in function,
with result going to TARGET if that's convenient
@@ -6809,6 +6848,13 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
maybe_emit_free_warning (exp);
break;
+ case BUILT_IN_THREAD_POINTER:
+ return expand_builtin_thread_pointer (exp, target);
+
+ case BUILT_IN_SET_THREAD_POINTER:
+ expand_builtin_set_thread_pointer (exp);
+ return const0_rtx;
+
default: /* just do library call, if unknown builtin */
break;
}