aboutsummaryrefslogtreecommitdiff
path: root/gcc/builtins.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r--gcc/builtins.c36
1 files changed, 23 insertions, 13 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 3dedc5b336a..0eae8bfd6df 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -30,8 +30,6 @@ Boston, MA 02111-1307, USA. */
#include "hard-reg-set.h"
#include "except.h"
#include "function.h"
-#include "insn-flags.h"
-#include "insn-codes.h"
#include "insn-config.h"
#include "expr.h"
#include "recog.h"
@@ -700,7 +698,7 @@ expand_builtin_longjmp (buf_addr, value)
/* We have to pass a value to the nonlocal_goto pattern that will
get copied into the static_chain pointer, but it does not matter
what that value is, because builtin_setjmp does not use it. */
- emit_insn (gen_nonlocal_goto (value, fp, stack, lab));
+ emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
else
#endif
{
@@ -720,12 +718,17 @@ expand_builtin_longjmp (buf_addr, value)
__builtin_setjmp target in the same function. However, we've
already cautioned the user that these functions are for
internal exception handling use only. */
- for (insn = get_last_insn ();
- GET_CODE (insn) != JUMP_INSN;
- insn = PREV_INSN (insn))
- continue;
- REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
- REG_NOTES (insn));
+ for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
+ {
+ if (GET_CODE (insn) == JUMP_INSN)
+ {
+ REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
+ REG_NOTES (insn));
+ break;
+ }
+ else if (GET_CODE (insn) == CALL_INSN)
+ break;
+ }
}
/* Get a MEM rtx for expression EXP which is the address of an operand
@@ -3606,9 +3609,12 @@ expand_builtin (exp, target, subtarget, mode, ignore)
return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
case BUILT_IN_EH_RETURN:
expand_builtin_eh_return (TREE_VALUE (arglist),
- TREE_VALUE (TREE_CHAIN (arglist)),
- TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))));
+ TREE_VALUE (TREE_CHAIN (arglist)));
return const0_rtx;
+#ifdef EH_RETURN_DATA_REGNO
+ case BUILT_IN_EH_RETURN_DATA_REGNO:
+ return expand_builtin_eh_return_data_regno (arglist);
+#endif
case BUILT_IN_VARARGS_START:
return expand_builtin_va_start (0, arglist);
case BUILT_IN_STDARG_START:
@@ -3659,10 +3665,14 @@ fold_builtin_constant_p (arglist)
has side effects, show we don't know it to be a constant.
Likewise if it's a pointer or aggregate type since in those
case we only want literals, since those are only optimized
- when generating RTL, not later. */
+ when generating RTL, not later.
+ And finally, if we are compiling an initializer, not code, we
+ need to return a definite result now; there's not going to be any
+ more optimization done. */
if (TREE_SIDE_EFFECTS (arglist) || cse_not_expected
|| AGGREGATE_TYPE_P (TREE_TYPE (arglist))
- || POINTER_TYPE_P (TREE_TYPE (arglist)))
+ || POINTER_TYPE_P (TREE_TYPE (arglist))
+ || cfun == 0)
return integer_zero_node;
return 0;