aboutsummaryrefslogtreecommitdiff
path: root/gcc/builtins.c
diff options
context:
space:
mode:
authorDavid Daney <ddaney@avtrex.com>2007-07-11 04:13:10 +0000
committerDavid Daney <daney@gcc.gnu.org>2007-07-11 04:13:10 +0000
commit677feb77ce2344d316c2026a4a1dd95677b5d39e (patch)
tree401faf6e2bf0facb662a8bc501c9a5f2f15df8ee /gcc/builtins.c
parent3a0e695acde4dc47332f6c22a93d2763e186b2f1 (diff)
downloadgcc-677feb77ce2344d316c2026a4a1dd95677b5d39e.zip
gcc-677feb77ce2344d316c2026a4a1dd95677b5d39e.tar.gz
gcc-677feb77ce2344d316c2026a4a1dd95677b5d39e.tar.bz2
builtins.def (BUILT_IN_CLEAR_CACHE): New builtin.
2007-07-10 David Daney <ddaney@avtrex.com> * builtins.def (BUILT_IN_CLEAR_CACHE): New builtin. * builtins.c (expand_builtin___clear_cache): New function. (expand_builtin): Call expand_builtin___clear_cache for BUILT_IN_CLEAR_CACHE case. * doc/extend.texi (__builtin___clear_cache): Document new builtin. * doc/md.texi (clear_cache): Document new instruction pattern. * testsuite/gcc.dg/builtins-64.c: New test. From-SVN: r126535
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r--gcc/builtins.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c
index c01d4d0..da76f61 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -5512,6 +5512,59 @@ expand_builtin_profile_func (bool exitp)
return const0_rtx;
}
+/* Expand a call to __builtin___clear_cache. */
+
+static rtx
+expand_builtin___clear_cache (tree exp ATTRIBUTE_UNUSED)
+{
+#ifndef HAVE_clear_cache
+#ifdef CLEAR_INSN_CACHE
+ /* There is no "clear_cache" insn, and __clear_cache() in libgcc
+ does something. Just do the default expansion to a call to
+ __clear_cache(). */
+ return NULL_RTX;
+#else
+ /* There is no "clear_cache" insn, and __clear_cache() in libgcc
+ does nothing. There is no need to call it. Do nothing. */
+ return const0_rtx;
+#endif /* CLEAR_INSN_CACHE */
+#else
+ /* We have a "clear_cache" insn, and it will handle everything. */
+ tree begin, end;
+ rtx begin_rtx, end_rtx;
+ enum insn_code icode;
+
+ /* We must not expand to a library call. If we did, any
+ fallback library function in libgcc that might contain a call to
+ __builtin___clear_cache() would recurse infinitely. */
+ if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
+ {
+ error ("both arguments to %<__builtin___clear_cache%> must be pointers");
+ return const0_rtx;
+ }
+
+ if (HAVE_clear_cache)
+ {
+ icode = CODE_FOR_clear_cache;
+
+ begin = CALL_EXPR_ARG (exp, 0);
+ begin_rtx = expand_expr (begin, NULL_RTX, Pmode, EXPAND_NORMAL);
+ begin_rtx = convert_memory_address (Pmode, begin_rtx);
+ if (!insn_data[icode].operand[0].predicate (begin_rtx, Pmode))
+ begin_rtx = copy_to_mode_reg (Pmode, begin_rtx);
+
+ end = CALL_EXPR_ARG (exp, 1);
+ end_rtx = expand_expr (end, NULL_RTX, Pmode, EXPAND_NORMAL);
+ end_rtx = convert_memory_address (Pmode, end_rtx);
+ if (!insn_data[icode].operand[1].predicate (end_rtx, Pmode))
+ end_rtx = copy_to_mode_reg (Pmode, end_rtx);
+
+ emit_insn (gen_clear_cache (begin_rtx, end_rtx));
+ }
+ return const0_rtx;
+#endif /* HAVE_clear_cache */
+}
+
/* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
static rtx
@@ -6198,6 +6251,12 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
return const0_rtx;
return expand_builtin_next_arg ();
+ case BUILT_IN_CLEAR_CACHE:
+ target = expand_builtin___clear_cache (exp);
+ if (target)
+ return target;
+ break;
+
case BUILT_IN_CLASSIFY_TYPE:
return expand_builtin_classify_type (exp);