diff options
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/builtins.c | 48 | ||||
-rw-r--r-- | gcc/builtins.def | 1 |
3 files changed, 55 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 24b6342..c105919 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2004-04-26 Richard Kenner <kenner@vlsi1.ultra.nyu.edu> + + * builtins.c (expand_builtin_update_setjmp_buf): New function. + (expand_builtin, case BUILT_IN_UPDATE_SETJMP_BUF): New case. + * builtins.def (BUILT_IN_UPDATE_SETJMP_BUF): New code. + 2004-04-26 Paul Brook <paul@codesourcery.com> * config/arm/arm.c (arm_legitimate_index_p): Correct iwmmxt offsets. diff --git a/gcc/builtins.c b/gcc/builtins.c index 7c6cae1..e2d3934 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -84,6 +84,7 @@ static int apply_result_size (void); static rtx result_vector (int, rtx); #endif static rtx expand_builtin_setjmp (tree, rtx); +static void expand_builtin_update_setjmp_buf (rtx); static void expand_builtin_prefetch (tree); static rtx expand_builtin_apply_args (void); static rtx expand_builtin_apply_args_1 (void); @@ -738,6 +739,40 @@ expand_builtin_longjmp (rtx buf_addr, rtx value) } } +/* __builtin_update_setjmp_buf is passed a pointer to an array of five words + (not all will be used on all machines) that was passed to __builtin_setjmp. + It updates the stack pointer in that block to correspond to the current + stack pointer. */ + +static void +expand_builtin_update_setjmp_buf (rtx buf_addr) +{ + enum machine_mode sa_mode = Pmode; + rtx stack_save; + + +#ifdef HAVE_save_stack_nonlocal + if (HAVE_save_stack_nonlocal) + sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode; +#endif +#ifdef STACK_SAVEAREA_MODE + sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL); +#endif + + stack_save + = gen_rtx_MEM (sa_mode, + memory_address + (sa_mode, + plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode)))); + +#ifdef HAVE_setjmp + if (HAVE_setjmp) + emit_insn (gen_setjmp ()); +#endif + + emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX); +} + /* Expand a call to __builtin_prefetch. For a target that does not support data prefetch, evaluate the memory address argument in case it has side effects. */ @@ -5621,6 +5656,19 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode, return const0_rtx; } + /* This updates the setjmp buffer that is its argument with the value + of the current stack pointer. */ + case BUILT_IN_UPDATE_SETJMP_BUF: + if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE)) + { + rtx buf_addr + = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0); + + expand_builtin_update_setjmp_buf (buf_addr); + return const0_rtx; + } + break; + case BUILT_IN_TRAP: expand_builtin_trap (); return const0_rtx; diff --git a/gcc/builtins.def b/gcc/builtins.def index 7220625..297d9ee 100644 --- a/gcc/builtins.def +++ b/gcc/builtins.def @@ -598,6 +598,7 @@ DEF_EXT_LIB_BUILTIN (BUILT_IN_STRFMON, "strfmon", BT_FN_SSIZE_STRING_SIZE_CON DEF_LIB_BUILTIN (BUILT_IN_STRFTIME, "strftime", BT_FN_SIZE_STRING_SIZE_CONST_STRING_CONST_PTR, ATTR_FORMAT_STRFTIME_3_0) DEF_GCC_BUILTIN (BUILT_IN_TRAP, "trap", BT_FN_VOID, ATTR_NORETURN_NOTHROW_LIST) DEF_GCC_BUILTIN (BUILT_IN_UNWIND_INIT, "unwind_init", BT_FN_VOID, ATTR_NULL) +DEF_GCC_BUILTIN (BUILT_IN_UPDATE_SETJMP_BUF, "update_setjmp_buf", BT_FN_VOID_PTR_INT, ATTR_NULL) DEF_GCC_BUILTIN (BUILT_IN_VA_COPY, "va_copy", BT_FN_VOID_VALIST_REF_VALIST_ARG, ATTR_NULL) DEF_GCC_BUILTIN (BUILT_IN_VA_END, "va_end", BT_FN_VOID_VALIST_REF, ATTR_NULL) DEF_GCC_BUILTIN (BUILT_IN_VA_START, "va_start", BT_FN_VOID_VALIST_REF_VAR, ATTR_NULL) |