Index: builtins.def =================================================================== --- builtins.def (revision 125997) +++ builtins.def (working copy) @@ -1,6 +1,6 @@ /* This file contains the definitions and documentation for the builtins used in the GNU compiler. - Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006 + Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. This file is part of GCC. @@ -609,6 +609,8 @@ DEF_GCC_BUILTIN (BUILT_IN_APPLY_A DEF_GCC_BUILTIN (BUILT_IN_ARGS_INFO, "args_info", BT_FN_INT_INT, ATTR_NULL) DEF_GCC_BUILTIN (BUILT_IN_BSWAP32, "bswap32", BT_FN_UINT32_UINT32, ATTR_CONST_NOTHROW_LIST) DEF_GCC_BUILTIN (BUILT_IN_BSWAP64, "bswap64", BT_FN_UINT64_UINT64, ATTR_CONST_NOTHROW_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_CLEAR_CACHE, "__clear_cache", BT_FN_VOID_PTR_PTR, ATTR_NOTHROW_LIST) +DEF_GCC_BUILTIN (BUILT_IN_CLEAR_CACHE_INLINE_P, "clear_cache_inline_p", BT_FN_BOOL, ATTR_NOTHROW_LIST) DEF_LIB_BUILTIN (BUILT_IN_CALLOC, "calloc", BT_FN_PTR_SIZE_SIZE, ATTR_MALLOC_NOTHROW_LIST) DEF_GCC_BUILTIN (BUILT_IN_CLASSIFY_TYPE, "classify_type", BT_FN_INT_VAR, ATTR_NULL) DEF_GCC_BUILTIN (BUILT_IN_CLZ, "clz", BT_FN_INT_UINT, ATTR_CONST_NOTHROW_LIST) Index: builtins.c =================================================================== --- builtins.c (revision 125997) +++ builtins.c (working copy) @@ -5513,6 +5513,44 @@ expand_builtin_profile_func (bool exitp) return const0_rtx; } +/* Expand a call to _builtin___clear_cache. If the target does not + support the operation, return NULL_RTX so it expands as a call. */ +static rtx +expand_builtin_clear_cache (tree exp) +{ + tree begin, end; + rtx begin_rtx, end_rtx; + + if (!targetm.builtin_clear_cache_inline_p()) + return NULL_RTX; + + /* We must not expand to a library call if + __builtin_clear_cache_inline_p() returns true. If we did, the + fallback library function in libgcc would expand to a call to + _builtin___clear_cache() and we 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; + } + + begin = CALL_EXPR_ARG (exp, 0); + end = CALL_EXPR_ARG (exp, 1); + + /* Evaluate BEGIN and END. */ + begin_rtx = expand_expr (begin, NULL_RTX, Pmode, EXPAND_NORMAL); + begin_rtx = convert_memory_address (Pmode, begin_rtx); + + end_rtx = expand_expr (end, NULL_RTX, Pmode, EXPAND_NORMAL); + end_rtx = convert_memory_address (Pmode, end_rtx); + +#ifdef HAVE_clear_cache + if (HAVE_clear_cache) + emit_insn (gen_clear_cache (begin_rtx, end_rtx)); +#endif + return const0_rtx; +} + /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */ static rtx @@ -6181,6 +6219,16 @@ expand_builtin (tree exp, rtx target, rt 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_CLEAR_CACHE_INLINE_P: + /* This gets folded away. We should never get here. */ + gcc_unreachable(); + case BUILT_IN_CLASSIFY_TYPE: return expand_builtin_classify_type (exp); @@ -9558,6 +9606,14 @@ fold_builtin_unordered_cmp (tree fndecl, fold_build2 (code, type, arg0, arg1)); } +/* Fold function call to builtin clear_cache_inline_p. */ +static tree +fold_builtin_clear_cache_inline_p (tree type) +{ + int v = targetm.builtin_clear_cache_inline_p() ? 1 : 0; + return constant_boolean_node (v, type); +} + /* Fold a call to built-in function FNDECL with 0 arguments. IGNORE is true if the result of the function call is ignored. This function returns NULL_TREE if no simplification was possible. */ @@ -9581,6 +9637,9 @@ fold_builtin_0 (tree fndecl, bool ignore case BUILT_IN_CLASSIFY_TYPE: return fold_builtin_classify_type (NULL_TREE); + case BUILT_IN_CLEAR_CACHE_INLINE_P: + return fold_builtin_clear_cache_inline_p (type); + default: break; } Index: target.h =================================================================== --- target.h (revision 125997) +++ target.h (working copy) @@ -855,6 +855,9 @@ struct gcc_target bits in the bitmap passed in. */ void (*live_on_entry) (bitmap); + /* Returns true if __builtin_clear_cache will expand in-line. */ + bool (*builtin_clear_cache_inline_p) (void); + /* True if unwinding tables should be generated by default. */ bool unwind_tables_default; Index: target-def.h =================================================================== --- target-def.h (revision 125997) +++ target-def.h (working copy) @@ -649,6 +649,10 @@ Foundation, 51 Franklin Street, Fifth Fl TARGET_CXX_ADJUST_CLASS_AT_DEFINITION \ } +#ifndef TARGET_BUILTIN_CLEAR_CACHE_INLINE_P +#define TARGET_BUILTIN_CLEAR_CACHE_INLINE_P hook_bool_void_false +#endif + /* The whole shebang. */ #define TARGET_INITIALIZER \ { \ @@ -731,6 +735,7 @@ Foundation, 51 Franklin Street, Fifth Fl TARGET_SECONDARY_RELOAD, \ TARGET_CXX, \ TARGET_EXTRA_LIVE_ON_ENTRY, \ + TARGET_BUILTIN_CLEAR_CACHE_INLINE_P, \ TARGET_UNWIND_TABLES_DEFAULT, \ TARGET_HAVE_NAMED_SECTIONS, \ TARGET_HAVE_SWITCHABLE_BSS_SECTIONS, \ Index: doc/extend.texi =================================================================== --- doc/extend.texi (revision 125997) +++ doc/extend.texi (working copy) @@ -6086,6 +6086,23 @@ if (__builtin_expect (ptr != NULL, 1)) when testing pointer or floating-point values. @end deftypefn +@deftypefn {Built-in Function} void __builtin___clear_cache (char *@var{begin}, char *@var{end}) +This functions is used to flush the processor's instruction cache for +the region of memory between @var{begin} and @var{end}. Some +targets require that the instruction cache be flushed, after modifying +memory containing code, in order to obtain deterministic behavior. + +If the target does not require instruction cache flushes, +@code{__builtin___clear_cache} has no effect. Otherwise either +instructions are emitted in-line to clear the instruction cache or a +call to the @code{__clear_cache} function in libgcc is made. +@end deftypefn + +@deftypefn {Built-in Function} bool __builtin_clear_cache_inline_p (void) +This function returns @code{false} if @code{__builtin___clear_cache} +will result in a call to the @code{__clear_cache} function in libgcc. +@end deftypefn + @deftypefn {Built-in Function} void __builtin_prefetch (const void *@var{addr}, ...) This function is used to minimize cache-miss latency by moving data into a cache before it is accessed. Index: doc/tm.texi =================================================================== --- doc/tm.texi (revision 125997) +++ doc/tm.texi (working copy) @@ -10093,6 +10093,15 @@ to have to make special provisions in @c to reserve space for caller-saved target registers. @end deftypefn +@deftypefn {Target Hook} bool TARGET_BUILTIN_CLEAR_CACHE_INLINE_P (void) +This target hook returns @code{true} if the built-in function +@code{_builtin___clear_cache} (char * @var{begin}, char * @var{end}) +will be expanded in-line. Otherwise if @code{false} is returned, the +built-in will expand to a call to the library function +@code{__clear_cache} (char * @var{begin}, char * @var{end}). By +default, the hook returns @code{false}. +@end deftypefn + @defmac POWI_MAX_MULTS If defined, this macro is interpreted as a signed integer C expression that specifies the maximum number of floating point multiplications Index: testsuite/gcc.dg/builtins-64.c =================================================================== --- testsuite/gcc.dg/builtins-64.c (revision 0) +++ testsuite/gcc.dg/builtins-64.c (revision 0) @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-optimized" } */ + +int f() +{ + /* We must fold away __builtin_clear_cache_inline_p. */ + return __builtin_clear_cache_inline_p(); +} + +/* { dg-final { scan-tree-dump-not "__builtin_clear_cache_inline_p" "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ Index: testsuite/gcc.dg/builtins-65.c =================================================================== --- testsuite/gcc.dg/builtins-65.c (revision 0) +++ testsuite/gcc.dg/builtins-65.c (revision 0) @@ -0,0 +1,8 @@ +/* { dg-do run } */ + +int main () +{ + char *mem = __builtin_alloca (40); + __builtin___clear_cache (mem, mem + 40); + return 0; +}