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. @@ -640,6 +640,7 @@ DEF_EXT_LIB_BUILTIN (BUILT_IN_FFS, "f DEF_EXT_LIB_BUILTIN (BUILT_IN_FFSIMAX, "ffsimax", BT_FN_INT_INTMAX, ATTR_CONST_NOTHROW_LIST) DEF_EXT_LIB_BUILTIN (BUILT_IN_FFSL, "ffsl", BT_FN_INT_LONG, ATTR_CONST_NOTHROW_LIST) DEF_EXT_LIB_BUILTIN (BUILT_IN_FFSLL, "ffsll", BT_FN_INT_LONGLONG, ATTR_CONST_NOTHROW_LIST) +DEF_GCC_BUILTIN (BUILT_IN_FLUSH_ICACHE, "flush_icache", BT_FN_VOID_PTR_SIZE, ATTR_NOTHROW_LIST) DEF_EXT_LIB_BUILTIN (BUILT_IN_FORK, "fork", BT_FN_PID, ATTR_NOTHROW_LIST) DEF_GCC_BUILTIN (BUILT_IN_FRAME_ADDRESS, "frame_address", BT_FN_PTR_UINT, ATTR_NULL) DEF_LIB_BUILTIN (BUILT_IN_FREE, "free", BT_FN_VOID_PTR, ATTR_NOTHROW_LIST) Index: builtins.c =================================================================== --- builtins.c (revision 125997) +++ builtins.c (working copy) @@ -5513,6 +5513,39 @@ expand_builtin_profile_func (bool exitp) return const0_rtx; } +/* Expand a call to _builtin_flush_icache. If the target does not + support the operation, it is a nop. */ +static rtx +expand_builtin_flush_icache (tree exp) +{ + tree location, len; + rtx location_rtx, len_rtx; + + if (!validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) + return NULL_RTX; + + location = CALL_EXPR_ARG (exp, 0); + len = CALL_EXPR_ARG (exp, 1); + + /* Evaluate LOCATION in case it has side-effects. */ + location_rtx = expand_expr (location, NULL_RTX, Pmode, EXPAND_NORMAL); + location_rtx = convert_memory_address (Pmode, location_rtx); + + /* If the LEN parameter is zero, return. */ + if (integer_zerop (len)) + return const0_rtx; + + len_rtx = expand_normal (len); + +#ifdef HAVE_flush_icache + if (HAVE_flush_icache) + { + emit_insn (gen_flush_icache (location_rtx, len_rtx)); + } +#endif + return const0_rtx; +} + /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */ static rtx @@ -6590,6 +6623,9 @@ expand_builtin (tree exp, rtx target, rt case BUILT_IN_PROFILE_FUNC_EXIT: return expand_builtin_profile_func (true); + case BUILT_IN_FLUSH_ICACHE: + return expand_builtin_flush_icache (exp); + case BUILT_IN_INIT_TRAMPOLINE: return expand_builtin_init_trampoline (exp); case BUILT_IN_ADJUST_TRAMPOLINE: @@ -9558,6 +9594,22 @@ fold_builtin_unordered_cmp (tree fndecl, fold_build2 (code, type, arg0, arg1)); } +/* Fold function call to builtin flush_icache. Return + NULL_TREE if no simplification can be made. */ + +static tree +fold_builtin_flush_icache (tree location, tree len) +{ + if (! validate_arg (location, POINTER_TYPE) + || ! validate_arg (len, INTEGER_TYPE)) + return NULL_TREE; + + /* If len parameter is zero, do nothing. */ + if (integer_zerop (len)) + return omit_one_operand (void_type_node, location, len); + return NULL_TREE; +} + /* 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. */ @@ -10068,6 +10120,8 @@ fold_builtin_2 (tree fndecl, tree arg0, case BUILT_IN_VFPRINTF: return fold_builtin_fprintf (fndecl, arg0, arg1, NULL_TREE, ignore, fcode); + case BUILT_IN_FLUSH_ICACHE: + return fold_builtin_flush_icache (arg0, arg1); default: break; 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" } */ + +void f() +{ + char *memory = __builtin_alloca(40); + __builtin_flush_icache(memory, 40); +} + +/* { dg-final { scan-tree-dump "__builtin_flush_icache" "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,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-optimized" } */ + +void f() +{ + char *memory = __builtin_alloca(40); + /* __builtin_flush_icache should be folded away for size == 0. */ + __builtin_flush_icache(memory, 0); +} + +/* { dg-final { scan-tree-dump-not "__builtin_flush_icache" "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ Index: doc/extend.texi =================================================================== --- doc/extend.texi (revision 125997) +++ doc/extend.texi (working copy) @@ -6086,6 +6086,19 @@ if (__builtin_expect (ptr != NULL, 1)) when testing pointer or floating-point values. @end deftypefn +@deftypefn {Built-in Function} void __builtin_flush_icache (const void *@var{addr}, size_t @var{len}) +This functions is used to flush the processor's instruction cache for +the region of memory of length @var{len} at location @var{addr}. 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 or otherwise +does not have support for @code{__builtin_flush_icache}, the address +expression is evaluated if it includes side effects but no other code +is generated. Currently MIPS is the only target with support for +@code{__builtin_flush_icache}. +@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.