aboutsummaryrefslogtreecommitdiff
path: root/gcc/calls.c
diff options
context:
space:
mode:
authorJim Wilson <wilson@cygnus.com>2000-02-10 21:00:09 +0000
committerJim Wilson <wilson@gcc.gnu.org>2000-02-10 13:00:09 -0800
commitc2939b5700388b67a717e22580f2ac5c9314797e (patch)
treecd7e01baf94c3ea9f1ce4863348b648f9540e2e5 /gcc/calls.c
parentaaf0766e9f897b2fbce053083d85cb739cb509d2 (diff)
downloadgcc-c2939b5700388b67a717e22580f2ac5c9314797e.zip
gcc-c2939b5700388b67a717e22580f2ac5c9314797e.tar.gz
gcc-c2939b5700388b67a717e22580f2ac5c9314797e.tar.bz2
Fix for ia64 setjmp miscompilation problem.
* calls.c (expand_call): When emitting a NOTE_INSN_SETJMP, search for the CALL_INSN, and emit the note immediately after it. From-SVN: r31902
Diffstat (limited to 'gcc/calls.c')
-rw-r--r--gcc/calls.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/gcc/calls.c b/gcc/calls.c
index 03261c0..071a89e 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -1602,6 +1602,7 @@ expand_call (exp, target, ignore)
or 0 if the function is computed (not known by name). */
tree fndecl = 0;
char *name = 0;
+ rtx before_call;
/* Register in which non-BLKmode value will be returned,
or 0 if no value or if value is BLKmode. */
@@ -1840,8 +1841,9 @@ expand_call (exp, target, ignore)
if (is_integrable)
{
rtx temp;
+
#ifdef ACCUMULATE_OUTGOING_ARGS
- rtx before_call = get_last_insn ();
+ before_call = get_last_insn ();
#endif
temp = expand_inline_function (fndecl, actparms, target,
@@ -2383,6 +2385,10 @@ expand_call (exp, target, ignore)
/* Perform postincrements before actually calling the function. */
emit_queue ();
+ /* Save a pointer to the last insn before the call, so that we can
+ later safely search backwards to find the CALL_INSN. */
+ before_call = get_last_insn ();
+
/* All arguments and registers used for the call must be set up by now! */
/* Generate the actual call instruction. */
@@ -2463,7 +2469,18 @@ expand_call (exp, target, ignore)
if (returns_twice)
{
- emit_note (name, NOTE_INSN_SETJMP);
+ /* The NOTE_INSN_SETJMP note must be emitted immediately after the
+ CALL_INSN. Some ports emit more than just a CALL_INSN above, so
+ we must search for it here. */
+ rtx last = get_last_insn ();
+ while (GET_CODE (last) != CALL_INSN)
+ {
+ last = PREV_INSN (last);
+ /* There was no CALL_INSN? */
+ if (last == before_call)
+ abort ();
+ }
+ emit_note_after (NOTE_INSN_SETJMP, last);
current_function_calls_setjmp = 1;
}