summaryrefslogtreecommitdiff
path: root/gcc/config/alpha/alpha.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/alpha/alpha.c')
-rw-r--r--gcc/config/alpha/alpha.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index 9f5dae29054..e13c5f9fc57 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -26,6 +26,8 @@ along with GCC; see the file COPYING3. If not see
#include "target.h"
#include "rtl.h"
#include "tree.h"
+#include "stringpool.h"
+#include "attribs.h"
#include "memmodel.h"
#include "gimple.h"
#include "df.h"
@@ -9456,6 +9458,25 @@ And in the noreturn case:
if (current_function_has_exception_handlers ())
alpha_pad_function_end ();
+
+ /* CALL_PAL that implements trap insn, updates program counter to point
+ after the insn. In case trap is the last insn in the function,
+ emit NOP to guarantee that PC remains inside function boundaries.
+ This workaround is needed to get reliable backtraces. */
+
+ rtx_insn *insn = prev_active_insn (get_last_insn ());
+
+ if (insn && NONJUMP_INSN_P (insn))
+ {
+ rtx pat = PATTERN (insn);
+ if (GET_CODE (pat) == PARALLEL)
+ {
+ rtx vec = XVECEXP (pat, 0, 0);
+ if (GET_CODE (vec) == TRAP_IF
+ && XEXP (vec, 0) == const1_rtx)
+ emit_insn_after (gen_unop (), insn);
+ }
+ }
}
static void